7878#undef Atom
7979#undef Time
8080
81+ #include <nx-X11/Xatom.h>
82+
8183#ifdef NXAGENT_FIXKEYS
8284#include "inputstr.h"
8385#include "input.h"
@@ -690,6 +692,103 @@ static void nxagentSwitchDeferMode(void)
690692 }
691693}
692694
695+ void setWinNameSuffix (const char * suffix )
696+ {
697+ static unsigned char * prev = NULL ;
698+ char * pre = " (" ;
699+ char * post = ")" ;
700+ char * newname ;
701+
702+ if (suffix ) {
703+ if (!(newname = calloc (strlen (nxagentWindowName ) + strlen (pre ) + strlen (suffix ) + strlen (post ) + 1 , sizeof (char ))))
704+ {
705+ fprintf (stderr , "%s: malloc failed" , __func__ );
706+ return ;
707+ }
708+ strcpy (newname , nxagentWindowName );
709+ strcpy (newname + strlen (nxagentWindowName ), pre );
710+ strcpy (newname + strlen (nxagentWindowName ) + strlen (pre ), suffix );
711+ strcpy (newname + strlen (nxagentWindowName ) + strlen (pre ) + strlen (suffix ), post );
712+ free (prev );
713+ prev = NULL ;
714+ XFetchName (nxagentDisplay , nxagentDefaultWindows [0 ], & prev );
715+ XStoreName (nxagentDisplay , nxagentDefaultWindows [0 ], newname );
716+ free (newname );
717+ }
718+ else
719+ {
720+ if (prev )
721+ {
722+ XStoreName (nxagentDisplay , nxagentDefaultWindows [0 ], prev );
723+ free (prev );
724+ prev = NULL ;
725+ }
726+ else
727+ {
728+ XStoreName (nxagentDisplay , nxagentDefaultWindows [0 ], nxagentWindowName );
729+ }
730+ }
731+ }
732+
733+ static Bool autograb = False ;
734+ static Bool inputlock = False ;
735+
736+ static void nxagentAutoGrab (void )
737+ {
738+ if (!inputlock )
739+ {
740+ #ifdef DEBUG
741+ if (autograb )
742+ fprintf (stderr , "disabling autograb\n" );
743+ else
744+ fprintf (stderr , "enabling autograb\n" );
745+ #endif
746+
747+ if (!autograb )
748+ {
749+ nxagentGrabPointerAndKeyboard (NULL );
750+ setWinNameSuffix ("autograb on" );
751+ }
752+ else
753+ {
754+ nxagentUngrabPointerAndKeyboard (NULL );
755+ setWinNameSuffix (NULL );
756+ }
757+ autograb = !autograb ;
758+ }
759+ }
760+
761+ /* TODO: drop inputlock when switching to Fullscreen */
762+ static void nxagentLockInput (void )
763+ {
764+ #ifdef DEBUG
765+ if (inputlock )
766+ fprintf (stderr , "releasing inputlock\n" );
767+ else
768+ fprintf (stderr , "activating inputlock\n" );
769+ #endif
770+
771+ if (!inputlock )
772+ {
773+ setWinNameSuffix ("input locked" );
774+ XGrabPointer (nxagentDisplay ,nxagentDefaultWindows [0 ], True ,
775+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask | EnterWindowMask | LeaveWindowMask ,
776+ GrabModeAsync , GrabModeAsync , nxagentDefaultWindows [0 ], None , CurrentTime );
777+ }
778+ else
779+ {
780+ nxagentUngrabPointerAndKeyboard (NULL );
781+ XTextProperty name = {
782+ .value = (unsigned char * )nxagentWindowName ,
783+ .encoding = XA_STRING ,
784+ .format = 8 ,
785+ .nitems = strlen ((char * ) name .value )
786+ };
787+ setWinNameSuffix (NULL );
788+ }
789+ inputlock = !inputlock ;
790+ }
791+
693792static Bool nxagentExposurePredicate (Display * display , XEvent * event , XPointer window )
694793{
695794 /*
@@ -1083,6 +1182,18 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
10831182
10841183 break ;
10851184 }
1185+ case doAutoGrab :
1186+ {
1187+ nxagentAutoGrab ();
1188+
1189+ break ;
1190+ }
1191+ case doLockInput :
1192+ {
1193+ nxagentLockInput ();
1194+
1195+ break ;
1196+ }
10861197 default :
10871198 {
10881199 FatalError ("nxagentDispatchEvent: handleKeyPress returned unknown value\n" );
@@ -1537,6 +1648,17 @@ FIXME: Don't enqueue the KeyRelease event if the key was
15371648 }
15381649 }
15391650
1651+ /* FIXME: only when in windowed mode! */
1652+ if (autograb )
1653+ {
1654+ if (X .xfocus .window == nxagentDefaultWindows [0 ] && X .xfocus .mode == NotifyNormal )
1655+ {
1656+ #ifdef DEBUG
1657+ fprintf (stderr , "%s: (FocusIn): grabbing\n" , __func__ );
1658+ #endif
1659+ nxagentGrabPointerAndKeyboard (NULL );
1660+ }
1661+ }
15401662 break ;
15411663 }
15421664 case FocusOut :
@@ -1615,6 +1737,19 @@ FIXME: Don't enqueue the KeyRelease event if the key was
16151737
16161738 #endif /* NXAGENT_FIXKEYS */
16171739
1740+ if (autograb )
1741+ {
1742+ XlibWindow w = NULL ;
1743+ int revert_to ;
1744+ XGetInputFocus (nxagentDisplay , & w , & revert_to );
1745+ if (w != nxagentDefaultWindows [0 ] && X .xfocus .mode == NotifyWhileGrabbed )
1746+ {
1747+ #ifdef DEBUG
1748+ fprintf (stderr , "%s: (FocusOut): ungrabbing\n" , __func__ );
1749+ #endif
1750+ nxagentUngrabPointerAndKeyboard (NULL );
1751+ }
1752+ }
16181753 break ;
16191754 }
16201755 case KeymapNotify :
@@ -3876,13 +4011,26 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
38764011 fprintf (stderr , "nxagentGrabPointerAndKeyboard: Going to grab the keyboard in context [B1].\n" );
38774012 #endif
38784013
3879- result = XGrabKeyboard (nxagentDisplay , nxagentFullscreenWindow ,
3880- True , GrabModeAsync , GrabModeAsync , now );
4014+ if (nxagentFullscreenWindow )
4015+ result = XGrabKeyboard (nxagentDisplay , nxagentFullscreenWindow ,
4016+ True , GrabModeAsync , GrabModeAsync , now );
4017+ else
4018+ result = XGrabKeyboard (nxagentDisplay , RootWindow (nxagentDisplay , DefaultScreen (nxagentDisplay )),
4019+ True , GrabModeAsync , GrabModeAsync , now );
38814020
38824021 if (result != GrabSuccess )
38834022 {
4023+ #ifdef DEBUG
4024+ fprintf (stderr , "%s: keyboard grab failed.\n" , __func__ );
4025+ #endif
38844026 return ;
38854027 }
4028+ #ifdef DEBUG
4029+ else
4030+ {
4031+ fprintf (stderr , "%s: keyboard grab successful.\n" , __func__ );
4032+ }
4033+ #endif
38864034
38874035 /*
38884036 * The smart scheduler could be stopped while
@@ -3900,7 +4048,8 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
39004048 resource = nxagentWaitForResource (NXGetCollectGrabPointerResource ,
39014049 nxagentCollectGrabPointerPredicate );
39024050
3903- NXCollectGrabPointer (nxagentDisplay , resource ,
4051+ if (nxagentFullscreenWindow )
4052+ NXCollectGrabPointer (nxagentDisplay , resource ,
39044053 nxagentFullscreenWindow , True , NXAGENT_POINTER_EVENT_MASK ,
39054054 GrabModeAsync , GrabModeAsync , None , None , now );
39064055
0 commit comments