LINUX: Improved input handling
This commit is contained in:
parent
a9506354ee
commit
0011e75a6e
|
@ -56,6 +56,8 @@
|
|||
|
||||
extern void resetCursor(int x, int y);
|
||||
|
||||
extern Atom getWarpAtom(void);
|
||||
|
||||
/*
|
||||
* Various functions to release/acquire keyboard and mouse
|
||||
*/
|
||||
|
@ -67,7 +69,6 @@
|
|||
extern void updateKeyboardGrab(void);
|
||||
extern void setGrab(bool);
|
||||
extern bool shouldGrab(void);
|
||||
extern bool isGrabbed(void);
|
||||
|
||||
/*
|
||||
* get the current window width
|
||||
|
|
|
@ -80,7 +80,7 @@ static void ungrabKeyboard(void) {
|
|||
void updateKeyboardGrab(void) {
|
||||
if (!created)
|
||||
return;
|
||||
if (shouldGrab()) {
|
||||
if (isFullscreen() || shouldGrab()) {
|
||||
grabKeyboard();
|
||||
} else {
|
||||
ungrabKeyboard();
|
||||
|
|
|
@ -119,7 +119,7 @@ static bool blankCursor(void) {
|
|||
|
||||
static void updateCursor(void) {
|
||||
Cursor cursor;
|
||||
if (isGrabbed())
|
||||
if (shouldGrab())
|
||||
cursor = blank_cursor;
|
||||
else
|
||||
cursor = current_cursor;
|
||||
|
@ -152,7 +152,7 @@ static void ungrabPointer(void) {
|
|||
void updatePointerGrab(void) {
|
||||
if (!created)
|
||||
return;
|
||||
if (shouldGrab()) {
|
||||
if (isFullscreen() || shouldGrab()) {
|
||||
grabPointer();
|
||||
} else {
|
||||
ungrabPointer();
|
||||
|
@ -162,13 +162,15 @@ void updatePointerGrab(void) {
|
|||
|
||||
static void doWarpPointer(void ) {
|
||||
XEvent ignore_warp_guard;
|
||||
ignore_warp_guard.type = MotionNotify;
|
||||
ignore_warp_guard.type = ClientMessage;
|
||||
ignore_warp_guard.xclient.message_type = getWarpAtom();
|
||||
ignore_warp_guard.xclient.format = 8;
|
||||
// Tell event loop to start ignoring motion events
|
||||
ignore_warp_guard.xmotion.state = 1;
|
||||
ignore_warp_guard.xclient.data.b[0] = 1;
|
||||
XSendEvent(getDisplay(), getCurrentWindow(), False, 0, &ignore_warp_guard);
|
||||
XWarpPointer(getDisplay(), None, getCurrentWindow(), 0, 0, 0, 0, getWindowWidth()/2, getWindowHeight()/2);
|
||||
// Tell event loop to stop ignoring motion events
|
||||
ignore_warp_guard.xmotion.state = 0;
|
||||
ignore_warp_guard.xclient.data.b[0] = 0;
|
||||
XSendEvent(getDisplay(), getCurrentWindow(), False, 0, &ignore_warp_guard);
|
||||
|
||||
/* centerCursor();
|
||||
|
@ -189,7 +191,7 @@ static void doWarpPointer(void ) {
|
|||
}
|
||||
|
||||
static void warpPointer(void) {
|
||||
if (!pointer_grabbed || !isGrabbed())
|
||||
if (!pointer_grabbed || !shouldGrab())
|
||||
return;
|
||||
// Reset pointer to middle of screen if outside a certain inner border
|
||||
if (current_x < POINTER_WARP_BORDER || current_y < POINTER_WARP_BORDER ||
|
||||
|
|
|
@ -76,6 +76,7 @@ static bool grab;
|
|||
static bool ignore_motion_events;
|
||||
|
||||
static Display *display_connection = NULL;
|
||||
static Atom warp_atom;
|
||||
static int display_connection_usage = 0;
|
||||
|
||||
Display *getDisplay(void) {
|
||||
|
@ -89,11 +90,16 @@ Display *incDisplay(JNIEnv *env) {
|
|||
throwException(env, "Could not open X display");
|
||||
return NULL;
|
||||
}
|
||||
warp_atom = XInternAtom(getDisplay(), "ignore_warp_atom", False);
|
||||
}
|
||||
display_connection_usage++;
|
||||
return display_connection;
|
||||
}
|
||||
|
||||
Atom getWarpAtom(void) {
|
||||
return warp_atom;
|
||||
}
|
||||
|
||||
void decDisplay(void) {
|
||||
display_connection_usage--;
|
||||
if (display_connection_usage == 0)
|
||||
|
@ -140,12 +146,8 @@ bool isFullscreen(void) {
|
|||
return current_fullscreen;
|
||||
}
|
||||
|
||||
bool isGrabbed(void) {
|
||||
return grab;
|
||||
}
|
||||
|
||||
bool shouldGrab(void) {
|
||||
return current_fullscreen || (!input_released && grab);
|
||||
return !input_released && grab;
|
||||
}
|
||||
|
||||
void setGrab(bool new_grab) {
|
||||
|
@ -154,16 +156,22 @@ void setGrab(bool new_grab) {
|
|||
}
|
||||
|
||||
static void handleMotion(XMotionEvent *event) {
|
||||
if (event->send_event == True) {
|
||||
// We got a warp ignore message
|
||||
ignore_motion_events = event->state == 1 ? true : false;
|
||||
} else if (ignore_motion_events) {
|
||||
if (ignore_motion_events) {
|
||||
resetCursor(event->x, event->y);
|
||||
} else {
|
||||
handlePointerMotion(event);
|
||||
}
|
||||
}
|
||||
|
||||
static void checkInput(void) {
|
||||
Window win;
|
||||
int revert_mode;
|
||||
XGetInputFocus(getDisplay(), &win, &revert_mode);
|
||||
if (win == current_win) {
|
||||
acquireInput();
|
||||
focused = true;
|
||||
}
|
||||
}
|
||||
static void handleMessages() {
|
||||
XEvent event;
|
||||
Window win;
|
||||
|
@ -172,7 +180,9 @@ static void handleMessages() {
|
|||
XNextEvent(getDisplay(), &event);
|
||||
switch (event.type) {
|
||||
case ClientMessage:
|
||||
if ((event.xclient.format == 32) && ((Atom)event.xclient.data.l[0] == delete_atom))
|
||||
if (event.xclient.message_type == warp_atom) {
|
||||
ignore_motion_events = event.xclient.data.b[0] == 1 ? true : false;
|
||||
} else if ((event.xclient.format == 32) && ((Atom)event.xclient.data.l[0] == delete_atom))
|
||||
closerequested = true;
|
||||
break;
|
||||
case FocusOut:
|
||||
|
@ -183,11 +193,7 @@ static void handleMessages() {
|
|||
}
|
||||
break;
|
||||
case FocusIn:
|
||||
XGetInputFocus(getDisplay(), &win, &revert_mode);
|
||||
if (win == current_win) {
|
||||
acquireInput();
|
||||
focused = true;
|
||||
}
|
||||
checkInput();
|
||||
break;
|
||||
case MapNotify:
|
||||
dirty = true;
|
||||
|
@ -200,6 +206,7 @@ static void handleMessages() {
|
|||
dirty = true;
|
||||
break;
|
||||
case ButtonPress:
|
||||
checkInput();
|
||||
handleButtonPress(&(event.xbutton));
|
||||
break;
|
||||
case ButtonRelease:
|
||||
|
|
Loading…
Reference in New Issue