Skip to content

Commit 132a48b

Browse files
committed
add autograb mode and inputlock mode
Fixes #384 You can now toggle between autograb mode by pressing CTRL-ALT-G (default, can be adjusted in keystrokes.cfg). You can toogle inputlock mode (pointer stays in the nxagent window) by pressing CTRL-ALT-C.
1 parent 99e8cdf commit 132a48b

File tree

6 files changed

+179
-7
lines changed

6 files changed

+179
-7
lines changed

doc/nxagent/README.keystrokes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ reread_keystrokes
103103
forces nxagent to re-read the keystroke
104104
configuration. Useful to add/changes keystrokes for a running
105105
session.
106+
autograb
107+
enable/disable autograb mode
108+
lockinput
109+
lock/unlock pointer within nxagent window
106110

107111
Only in builds with certain debugging options enabled, ignored otherwise:
108112
force_synchronization

etc/keystrokes.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@
1717
<keystroke action="viewport_move_right" Control="1" AltMeta="1" key="Right" />
1818
<keystroke action="viewport_move_down" Control="1" AltMeta="1" key="Down" />
1919
<keystroke action="reread_keystrokes" Control="1" AltMeta="1" key="k" />
20+
<keystroke action="autograb" Control="1" AltMeta="1" key="g" />
21+
<keystroke action="lockinput" Control="1" AltMeta="1" key="c" />
2022
</keystrokes>

nx-X11/programs/Xserver/hw/nxagent/Events.c

Lines changed: 152 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@
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+
693792
static 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

nx-X11/programs/Xserver/hw/nxagent/Events.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ enum HandleEventResult
5151
doViewportRight,
5252
doViewportDown,
5353
doSwitchResizeMode,
54-
doSwitchDeferMode
54+
doSwitchDeferMode,
55+
doAutoGrab,
56+
doLockInput
5557
};
5658

5759
extern CARD32 nxagentLastEventTime;

nx-X11/programs/Xserver/hw/nxagent/Keystroke.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ char * nxagentSpecialKeystrokeNames[] = {
9191
"viewport_move_down",
9292

9393
"reread_keystrokes",
94+
95+
"autograb",
96+
"lockinput",
97+
9498
NULL,
9599
};
96100

@@ -126,6 +130,8 @@ struct nxagentSpecialKeystrokeMap default_map[] = {
126130
{KEYSTROKE_VIEWPORT_MOVE_DOWN, ControlMask | ShiftMask, True, XK_Down},
127131
{KEYSTROKE_VIEWPORT_MOVE_DOWN, ControlMask | ShiftMask, True, XK_KP_Down},
128132
{KEYSTROKE_REREAD_KEYSTROKES, ControlMask, True, XK_k},
133+
{KEYSTROKE_AUTOGRAB, ControlMask, True, XK_g},
134+
{KEYSTROKE_LOCKINPUT, ControlMask, True, XK_c},
129135
{KEYSTROKE_END_MARKER, 0, False, NoSymbol},
130136
};
131137
struct nxagentSpecialKeystrokeMap *map = default_map;
@@ -411,7 +417,7 @@ static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X)
411417
#endif
412418
while (cur->stroke != KEYSTROKE_END_MARKER) {
413419
#ifdef DEBUG
414-
fprintf(stderr, "%s: checking keysym '%c' (%d)\n", __func__, cur->keysym, cur->keysym);
420+
fprintf(stderr,"%s: keysym %d stroke %d, type %d\n", __func__, cur->keysym, cur->stroke, X->type);
415421
#endif
416422
if (cur->keysym == keysym[0] && modifier_matches(cur->modifierMask, cur->modifierAltMeta, X->state)) {
417423
#ifdef DEBUG
@@ -588,6 +594,12 @@ Bool nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
588594
if (X->type == KeyRelease)
589595
parse_keystroke_file(True);
590596
break;
597+
case KEYSTROKE_AUTOGRAB:
598+
*result = doAutoGrab;
599+
break;
600+
case KEYSTROKE_LOCKINPUT:
601+
*result = doLockInput;
602+
break;
591603
case KEYSTROKE_NOTHING: /* do nothing. difference to KEYSTROKE_IGNORE is the return value */
592604
case KEYSTROKE_END_MARKER: /* just to make gcc STFU */
593605
case KEYSTROKE_MAX:

nx-X11/programs/Xserver/hw/nxagent/Keystroke.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,15 @@ enum nxagentSpecialKeystroke {
6666

6767
KEYSTROKE_REREAD_KEYSTROKES = 21,
6868

69-
KEYSTROKE_NOTHING = 22,
69+
KEYSTROKE_AUTOGRAB = 22,
70+
KEYSTROKE_LOCKINPUT = 23,
71+
72+
KEYSTROKE_NOTHING = 24,
7073

7174
/* insert more here, increment KEYSTROKE_MAX accordingly.
7275
* then update string translation below */
7376

74-
KEYSTROKE_MAX = 23,
77+
KEYSTROKE_MAX = 25,
7578
};
7679

7780
struct nxagentSpecialKeystrokeMap {

0 commit comments

Comments
 (0)