Skip to content

Commit

Permalink
Make mouse capture more robust on Windows.
Browse files Browse the repository at this point in the history
* escape win/ctrl/alt keys to avoid losing capture
* detect mouse capture loss to deal with corner cases
  * main display switch (and change of resolution and/or scaling)
  * simultaneous press of win+tab, ctrl+esc or alt+tab
* restore mouse capture with a 1s retry period
* remove deprecated focus lost event

matlo/GIMX#641 matlo/GIMX#656
  • Loading branch information
matlo committed Apr 24, 2020
1 parent d8f150b commit 73ddeef
Show file tree
Hide file tree
Showing 12 changed files with 327 additions and 76 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ LDLIBS += -lgimxlog
LDFLAGS += -L../gimxhid
LDLIBS += -lgimxhid

LDFLAGS += -L../gimxtime
LDLIBS += -lgimxtime

ifeq ($(OS),Windows_NT)
CFLAGS += `sdl2-config --cflags`
LDLIBS += -lsetupapi -lws2_32
Expand Down
3 changes: 2 additions & 1 deletion include/ginput.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,6 @@ typedef enum {
GE_JOYDAMPERFORCE, /**< Joystick damper force */
GE_JOYSINEFORCE, /**< Joystick sine force */
GE_QUIT,
GE_FOCUS_LOST,
} GE_EventType;

typedef struct GE_KeyboardEvent {
Expand Down Expand Up @@ -454,6 +453,8 @@ int ginput_init(const GPOLL_INTERFACE * poll_interface, unsigned char mkb_src, i

/*
* \brief Grab/Release the mouse cursor (Windows) or grab/release all keyboard and mouse event devices (Linux).
*
* \return 1 if mouse is grabbed, 0 otherwise
*/
int ginput_grab_toggle();

Expand Down
6 changes: 5 additions & 1 deletion src/darwin/events.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,13 @@ const char* ev_keyboard_name(int id)
return NULL;
}

void ev_grab_input(int mode)
int ev_grab_input(int mode)
{
sdlinput_grab(mode);

// TODO capture mouse if mode is GE_GRAB_ON, release mouse otherwise

return 0;
}

void ev_sync_process()
Expand Down
4 changes: 2 additions & 2 deletions src/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
struct mkb_source {
int (* init)(const GPOLL_INTERFACE * poll_interface, int (*callback)(GE_Event*));
int (* get_src)();
void (* grab)(int mode);
int (* grab)(int mode);
const char * (* get_mouse_name)(int id);
const char * (* get_keyboard_name)(int id);
int (* sync_process)();
Expand Down Expand Up @@ -63,7 +63,7 @@ void * ev_joystick_get_hid(int joystick);
int ev_joystick_get_usb_ids(int joystick, unsigned short * vendor, unsigned short * product);
#endif

void ev_grab_input(int);
int ev_grab_input(int);
void ev_pump_events();
void ev_sync_process();

Expand Down
12 changes: 2 additions & 10 deletions src/ginput.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,16 +200,8 @@ void ginput_release_unused()

int ginput_grab_toggle()
{
if (grab)
{
ev_grab_input(GE_GRAB_OFF);
grab = 0;
}
else
{
ev_grab_input(GE_GRAB_ON);
grab = 1;
}
grab = ev_grab_input(grab ? GE_GRAB_OFF : GE_GRAB_ON);

return grab;
}

Expand Down
6 changes: 3 additions & 3 deletions src/linux/events.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,11 @@ void ev_joystick_close(int id) {
jsource->close(id);
}

void ev_grab_input(int mode) {
int ev_grab_input(int mode) {

CHECK_MKB_SOURCE();
CHECK_MKB_SOURCE(-1);

mkbsource->grab(mode);
return mkbsource->grab(mode);
}

void ev_quit(void) {
Expand Down
4 changes: 3 additions & 1 deletion src/linux/mkb.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ static void mkb_quit() {
}
}

static void mkb_grab(int mode) {
static int mkb_grab(int mode) {

int one = 1;
int* enable = NULL;
Expand All @@ -383,6 +383,8 @@ static void mkb_grab(int mode) {
ioctl(device->fd, EVIOCGRAB, enable);
device = device->next;
}

return mode;
}

static int mkb_get_src() {
Expand Down
4 changes: 3 additions & 1 deletion src/linux/xinput.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,14 +350,16 @@ static void xinput_quit() {
* Grab the pointer into the window.
* This function retries until success or 500ms have elapsed.
*/
static void xinput_grab(int mode __attribute__((unused))) {
static int xinput_grab(int mode) {

int i = 0;
while (XGrabPointer(dpy, win, True, 0, GrabModeAsync, GrabModeAsync, win, None, CurrentTime) != GrabSuccess
&& i < 50) {
usleep(10000);
++i;
}

return mode;
}

static char* get_name(unsigned char devtype, int index) {
Expand Down
8 changes: 6 additions & 2 deletions src/sdl/sdlinput.c
Original file line number Diff line number Diff line change
Expand Up @@ -990,9 +990,13 @@ static int sdlinput_joystick_get_usb_ids(int joystick, unsigned short * vendor,
return 0;
}

static void sdlinput_grab(int mode) {
static int sdlinput_grab(int mode) {

SDL_SetRelativeMouseMode((mode == GE_GRAB_ON) ? SDL_TRUE : SDL_FALSE);
if (SDL_SetRelativeMouseMode((mode == GE_GRAB_ON) ? SDL_TRUE : SDL_FALSE)) {
PRINT_ERROR_SDL("SDL_SetRelativeMouseMode");
}

return mode;
}

static int sdlinput_get_src() {
Expand Down
2 changes: 1 addition & 1 deletion src/sdl/sdlinput.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ int sdlinput_joystick_get_usb_ids(int joystick, unsigned short * vendor, unsigne

void sdlinput_sync_process();

void sdlinput_grab(int mode);
int sdlinput_grab(int mode);

#endif /* SDLINPUT_H_ */
Loading

0 comments on commit 73ddeef

Please sign in to comment.