Skip to content

Commit

Permalink
nxagent: Add autograb mode.
Browse files Browse the repository at this point in the history
 You can now toggle between autograb mode by pressing CTRL-ALT-G
 (default, can be adjusted in keystrokes.cfg).

 Fixes ArcticaProject#384.
 Fixes ArcticaProject#90.
  • Loading branch information
uli42 authored and sunweaver committed Jun 27, 2019
1 parent 1ebf785 commit 3c6cf29
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 5 deletions.
3 changes: 3 additions & 0 deletions doc/nxagent/README.keystrokes
Expand Up @@ -126,6 +126,9 @@ reread_keystrokes
Forces nxagent to re-read the keystroke configuration. Useful to
add/change keystrokes to a running session.

autograb
Toggles autograb mode

force_synchronization
Forces immediate drawing of elements to be synchronized which can
fix some visual bugs.
1 change: 1 addition & 0 deletions etc/keystrokes.cfg
Expand Up @@ -24,4 +24,5 @@
<keystroke action="viewport_scroll_down" Control="1" AltMeta="1" key="Down" />
<keystroke action="viewport_scroll_down" Control="1" AltMeta="1" key="KP_Down" />
<keystroke action="reread_keystrokes" Control="1" AltMeta="1" key="k" />
<keystroke action="autograb" Control="1" AltMeta="1" key="g" />
</keystrokes>
84 changes: 81 additions & 3 deletions nx-X11/programs/Xserver/hw/nxagent/Events.c
Expand Up @@ -678,6 +678,40 @@ static void nxagentSwitchDeferMode(void)
}
}

static Bool autograb = False;

static void nxagentEnableAutoGrab(void)
{
#ifdef DEBUG
fprintf(stderr, "enabling autograb\n");
#endif

nxagentGrabPointerAndKeyboard(NULL);
autograb = True;
}

static void nxagentDisableAutoGrab(void)
{
#ifdef DEBUG
fprintf(stderr, "disabling autograb\n");
#endif

nxagentUngrabPointerAndKeyboard(NULL);
autograb = False;
}

static void nxagentToggleAutoGrab(void)
{
/* autograb only works in windowed mode */
if (nxagentOption(Rootless) || nxagentOption(Fullscreen))
return;

if (!autograb)
nxagentEnableAutoGrab();
else
nxagentDisableAutoGrab();
}

static Bool nxagentExposurePredicate(Display *display, XEvent *event, XPointer window)
{
/*
Expand Down Expand Up @@ -1071,6 +1105,12 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)

break;
}
case doAutoGrab:
{
nxagentToggleAutoGrab();

break;
}
default:
{
FatalError("nxagentDispatchEvent: handleKeyPress returned unknown value\n");
Expand Down Expand Up @@ -1520,6 +1560,17 @@ FIXME: Don't enqueue the KeyRelease event if the key was
}
}

/* FIXME: only when in windowed mode! */
if (autograb)
{
if (X.xfocus.window == nxagentDefaultWindows[0] && X.xfocus.mode == NotifyNormal)
{
#ifdef DEBUG
fprintf(stderr, "%s: (FocusIn): grabbing\n", __func__);
#endif
nxagentGrabPointerAndKeyboard(NULL);
}
}
break;
}
case FocusOut:
Expand Down Expand Up @@ -1598,6 +1649,19 @@ FIXME: Don't enqueue the KeyRelease event if the key was

#endif /* NXAGENT_FIXKEYS */

if (autograb)
{
XlibWindow w;
int revert_to;
XGetInputFocus(nxagentDisplay, &w, &revert_to);
if (w != nxagentDefaultWindows[0] && X.xfocus.mode == NotifyWhileGrabbed)
{
#ifdef DEBUG
fprintf(stderr, "%s: (FocusOut): ungrabbing\n", __func__);
#endif
nxagentUngrabPointerAndKeyboard(NULL);
}
}
break;
}
case KeymapNotify:
Expand Down Expand Up @@ -3922,13 +3986,26 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to grab the keyboard in context [B1].\n");
#endif

result = XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow,
True, GrabModeAsync, GrabModeAsync, now);
if (nxagentFullscreenWindow)
result = XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow,
True, GrabModeAsync, GrabModeAsync, now);
else
result = XGrabKeyboard(nxagentDisplay, RootWindow(nxagentDisplay, DefaultScreen(nxagentDisplay)),
True, GrabModeAsync, GrabModeAsync, now);

if (result != GrabSuccess)
{
#ifdef DEBUG
fprintf(stderr, "%s: keyboard grab failed.\n", __func__);
#endif
return;
}
#ifdef DEBUG
else
{
fprintf(stderr, "%s: keyboard grab successful.\n", __func__);
}
#endif

/*
* The smart scheduler could be stopped while
Expand All @@ -3946,7 +4023,8 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
resource = nxagentWaitForResource(NXGetCollectGrabPointerResource,
nxagentCollectGrabPointerPredicate);

NXCollectGrabPointer(nxagentDisplay, resource,
if (nxagentFullscreenWindow)
NXCollectGrabPointer(nxagentDisplay, resource,
nxagentFullscreenWindow, True, NXAGENT_POINTER_EVENT_MASK,
GrabModeAsync, GrabModeAsync, None, None, now);

Expand Down
3 changes: 2 additions & 1 deletion nx-X11/programs/Xserver/hw/nxagent/Events.h
Expand Up @@ -51,7 +51,8 @@ enum HandleEventResult
doViewportRight,
doViewportDown,
doSwitchResizeMode,
doSwitchDeferMode
doSwitchDeferMode,
doAutoGrab,
};

extern CARD32 nxagentLastEventTime;
Expand Down
9 changes: 8 additions & 1 deletion nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
Expand Up @@ -100,6 +100,9 @@ char * nxagentSpecialKeystrokeNames[] = {
"viewport_scroll_down",

"reread_keystrokes",

"autograb",

NULL,
};

Expand Down Expand Up @@ -139,6 +142,7 @@ struct nxagentSpecialKeystrokeMap default_map[] = {
{KEYSTROKE_VIEWPORT_SCROLL_DOWN, ControlMask, True, XK_Down},
{KEYSTROKE_VIEWPORT_SCROLL_DOWN, ControlMask, True, XK_KP_Down},
{KEYSTROKE_REREAD_KEYSTROKES, ControlMask, True, XK_k},
{KEYSTROKE_AUTOGRAB, ControlMask, True, XK_g},
{KEYSTROKE_END_MARKER, 0, False, NoSymbol},
};
struct nxagentSpecialKeystrokeMap *map = default_map;
Expand Down Expand Up @@ -468,7 +472,7 @@ static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X)
#endif
for (struct nxagentSpecialKeystrokeMap *cur = map; cur->stroke != KEYSTROKE_END_MARKER; cur++) {
#ifdef DEBUG
fprintf(stderr, "%s: checking keysym '%c' (%d)\n", __func__, cur->keysym, cur->keysym);
fprintf(stderr,"%s: keysym %d stroke %d, type %d\n", __func__, cur->keysym, cur->stroke, X->type);
#endif
if (cur->keysym == keysym && modifier_matches(cur->modifierMask, cur->modifierAltMeta, X->state)) {
#ifdef DEBUG
Expand Down Expand Up @@ -632,6 +636,9 @@ Bool nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
if (X->type == KeyRelease)
nxagentInitKeystrokes(True);
break;
case KEYSTROKE_AUTOGRAB:
*result = doAutoGrab;
break;
case KEYSTROKE_NOTHING: /* do nothing. difference to KEYSTROKE_IGNORE is the return value */
case KEYSTROKE_END_MARKER: /* just to make gcc STFU */
case KEYSTROKE_MAX:
Expand Down
2 changes: 2 additions & 0 deletions nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
Expand Up @@ -73,6 +73,8 @@ enum nxagentSpecialKeystroke {

KEYSTROKE_REREAD_KEYSTROKES,

KEYSTROKE_AUTOGRAB,

KEYSTROKE_NOTHING,

/* insert more here and in the string translation */
Expand Down

0 comments on commit 3c6cf29

Please sign in to comment.