Commit 58183b7c authored by Ulrich Sibiller's avatar Ulrich Sibiller Committed by Mike Gabriel

nxagent: Add autograb mode.

You can now toggle between autograb mode by pressing CTRL-ALT-G (default, can be adjusted in keystrokes.cfg). Fixes ArcticaProject/nx-libs#384.
parent daa50fd8
...@@ -126,6 +126,9 @@ reread_keystrokes ...@@ -126,6 +126,9 @@ reread_keystrokes
Forces nxagent to re-read the keystroke configuration. Useful to Forces nxagent to re-read the keystroke configuration. Useful to
add/change keystrokes to a running session. add/change keystrokes to a running session.
autograb
Toggles autograb mode
force_synchronization force_synchronization
Forces immediate drawing of elements to be synchronized which can Forces immediate drawing of elements to be synchronized which can
fix some visual bugs. fix some visual bugs.
...@@ -24,4 +24,5 @@ ...@@ -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="Down" />
<keystroke action="viewport_scroll_down" Control="1" AltMeta="1" key="KP_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="reread_keystrokes" Control="1" AltMeta="1" key="k" />
<keystroke action="autograb" Control="1" AltMeta="1" key="g" />
</keystrokes> </keystrokes>
...@@ -674,6 +674,40 @@ static void nxagentSwitchDeferMode(void) ...@@ -674,6 +674,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) static Bool nxagentExposurePredicate(Display *display, XEvent *event, XPointer window)
{ {
/* /*
...@@ -1060,6 +1094,12 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate) ...@@ -1060,6 +1094,12 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
break; break;
} }
case doAutoGrab:
{
nxagentToggleAutoGrab();
break;
}
default: default:
{ {
FatalError("nxagentDispatchEvent: handleKeyPress returned unknown value\n"); FatalError("nxagentDispatchEvent: handleKeyPress returned unknown value\n");
...@@ -1519,6 +1559,17 @@ FIXME: Don't enqueue the KeyRelease event if the key was ...@@ -1519,6 +1559,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; break;
} }
case FocusOut: case FocusOut:
...@@ -1597,6 +1648,19 @@ FIXME: Don't enqueue the KeyRelease event if the key was ...@@ -1597,6 +1648,19 @@ FIXME: Don't enqueue the KeyRelease event if the key was
#endif /* NXAGENT_FIXKEYS */ #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; break;
} }
case KeymapNotify: case KeymapNotify:
...@@ -3827,13 +3891,26 @@ void nxagentGrabPointerAndKeyboard(XEvent *X) ...@@ -3827,13 +3891,26 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to grab the keyboard in context [B1].\n"); fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to grab the keyboard in context [B1].\n");
#endif #endif
result = XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow, if (nxagentFullscreenWindow)
True, GrabModeAsync, GrabModeAsync, now); result = XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow,
True, GrabModeAsync, GrabModeAsync, now);
else
result = XGrabKeyboard(nxagentDisplay, RootWindow(nxagentDisplay, DefaultScreen(nxagentDisplay)),
True, GrabModeAsync, GrabModeAsync, now);
if (result != GrabSuccess) if (result != GrabSuccess)
{ {
#ifdef DEBUG
fprintf(stderr, "%s: keyboard grab failed.\n", __func__);
#endif
return; return;
} }
#ifdef DEBUG
else
{
fprintf(stderr, "%s: keyboard grab successful.\n", __func__);
}
#endif
/* /*
* The smart scheduler could be stopped while * The smart scheduler could be stopped while
...@@ -3851,7 +3928,8 @@ void nxagentGrabPointerAndKeyboard(XEvent *X) ...@@ -3851,7 +3928,8 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
resource = nxagentWaitForResource(NXGetCollectGrabPointerResource, resource = nxagentWaitForResource(NXGetCollectGrabPointerResource,
nxagentCollectGrabPointerPredicate); nxagentCollectGrabPointerPredicate);
NXCollectGrabPointer(nxagentDisplay, resource, if (nxagentFullscreenWindow)
NXCollectGrabPointer(nxagentDisplay, resource,
nxagentFullscreenWindow, True, NXAGENT_POINTER_EVENT_MASK, nxagentFullscreenWindow, True, NXAGENT_POINTER_EVENT_MASK,
GrabModeAsync, GrabModeAsync, None, None, now); GrabModeAsync, GrabModeAsync, None, None, now);
......
...@@ -50,7 +50,8 @@ enum HandleEventResult ...@@ -50,7 +50,8 @@ enum HandleEventResult
doViewportRight, doViewportRight,
doViewportDown, doViewportDown,
doSwitchResizeMode, doSwitchResizeMode,
doSwitchDeferMode doSwitchDeferMode,
doAutoGrab,
}; };
extern CARD32 nxagentLastEventTime; extern CARD32 nxagentLastEventTime;
......
...@@ -99,6 +99,9 @@ char * nxagentSpecialKeystrokeNames[] = { ...@@ -99,6 +99,9 @@ char * nxagentSpecialKeystrokeNames[] = {
"viewport_scroll_down", "viewport_scroll_down",
"reread_keystrokes", "reread_keystrokes",
"autograb",
NULL, NULL,
}; };
...@@ -138,6 +141,7 @@ struct nxagentSpecialKeystrokeMap default_map[] = { ...@@ -138,6 +141,7 @@ struct nxagentSpecialKeystrokeMap default_map[] = {
{KEYSTROKE_VIEWPORT_SCROLL_DOWN, ControlMask, True, XK_Down}, {KEYSTROKE_VIEWPORT_SCROLL_DOWN, ControlMask, True, XK_Down},
{KEYSTROKE_VIEWPORT_SCROLL_DOWN, ControlMask, True, XK_KP_Down}, {KEYSTROKE_VIEWPORT_SCROLL_DOWN, ControlMask, True, XK_KP_Down},
{KEYSTROKE_REREAD_KEYSTROKES, ControlMask, True, XK_k}, {KEYSTROKE_REREAD_KEYSTROKES, ControlMask, True, XK_k},
{KEYSTROKE_AUTOGRAB, ControlMask, True, XK_g},
{KEYSTROKE_END_MARKER, 0, False, NoSymbol}, {KEYSTROKE_END_MARKER, 0, False, NoSymbol},
}; };
struct nxagentSpecialKeystrokeMap *map = default_map; struct nxagentSpecialKeystrokeMap *map = default_map;
...@@ -467,7 +471,7 @@ static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X) ...@@ -467,7 +471,7 @@ static enum nxagentSpecialKeystroke find_keystroke(XKeyEvent *X)
#endif #endif
for (struct nxagentSpecialKeystrokeMap *cur = map; cur->stroke != KEYSTROKE_END_MARKER; cur++) { for (struct nxagentSpecialKeystrokeMap *cur = map; cur->stroke != KEYSTROKE_END_MARKER; cur++) {
#ifdef DEBUG #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 #endif
if (cur->keysym == keysym && modifier_matches(cur->modifierMask, cur->modifierAltMeta, X->state)) { if (cur->keysym == keysym && modifier_matches(cur->modifierMask, cur->modifierAltMeta, X->state)) {
#ifdef DEBUG #ifdef DEBUG
...@@ -627,6 +631,9 @@ Bool nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result) ...@@ -627,6 +631,9 @@ Bool nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
if (X->type == KeyRelease) if (X->type == KeyRelease)
nxagentInitKeystrokes(True); nxagentInitKeystrokes(True);
break; break;
case KEYSTROKE_AUTOGRAB:
*result = doAutoGrab;
break;
case KEYSTROKE_NOTHING: /* do nothing. difference to KEYSTROKE_IGNORE is the return value */ case KEYSTROKE_NOTHING: /* do nothing. difference to KEYSTROKE_IGNORE is the return value */
case KEYSTROKE_END_MARKER: /* just to make gcc STFU */ case KEYSTROKE_END_MARKER: /* just to make gcc STFU */
case KEYSTROKE_MAX: case KEYSTROKE_MAX:
......
...@@ -73,6 +73,8 @@ enum nxagentSpecialKeystroke { ...@@ -73,6 +73,8 @@ enum nxagentSpecialKeystroke {
KEYSTROKE_REREAD_KEYSTROKES, KEYSTROKE_REREAD_KEYSTROKES,
KEYSTROKE_AUTOGRAB,
KEYSTROKE_NOTHING, KEYSTROKE_NOTHING,
/* insert more here and in the string translation */ /* insert more here and in the string translation */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment