From f197f4d96e1b87df46d35f2dd00e18b32cad4097 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Sun, 16 Jan 2022 11:18:46 +0100 Subject: [PATCH] add cursor autohide --- application/main.c | 2 +- application/player.c | 18 ++++++++++++++++++ application/window.c | 33 +++++++++++++++++++++++++++------ application/window.h | 10 +++++++++- 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/application/main.c b/application/main.c index 43d6c05..028a163 100644 --- a/application/main.c +++ b/application/main.c @@ -176,7 +176,7 @@ void AppMainLoop(XtAppContext app) { XtAppNextEvent(app, &event); if(app_player_window != 0 && event.xany.window == app_player_window) { - WindowPlayerWidgetEvent(GetMainWindow(), &event); + WindowHandlePlayerEvent(GetMainWindow(), &event); } else { XtDispatchEvent(&event); } diff --git a/application/player.c b/application/player.c index 6cdba87..4764e98 100644 --- a/application/player.c +++ b/application/player.c @@ -419,6 +419,23 @@ static Boolean get_player_window(XtPointer data) { return 0; } +#define CURSOR_AUTOHIDE_THRESHOLD_SEC 4 + +static Boolean hide_cursor(XtPointer data) { + MainWindow *win = data; + WindowHidePlayerCursor(win); + return 0; +} + +static void check_hide_cursor(Player *p) { + MainWindow *win = GetMainWindow(); + if(win->cursorhidden) return; + + if(p->playback_time - win->motion_playback_time > CURSOR_AUTOHIDE_THRESHOLD_SEC) { + AppExecProc(hide_cursor, win); + } +} + static void handle_json_rpc_event(Player *p, JSONValue *v, JSONValue *event) { if(!json_strcmp(event, "property-change")) { JSONValue *name = json_obj_get(&v->value.object, "name"); @@ -427,6 +444,7 @@ static void handle_json_rpc_event(Player *p, JSONValue *v, JSONValue *event) { if(data && data->type == JSON_NUMBER) { p->playback_time = data->value.number.value; //printf("playback-time: %f\n", p->playback_time); + check_hide_cursor(p); } } else if(!json_strcmp(name, "eof-reached")) { if(data && data->type == JSON_LITERAL && data->value.literal.literal == JSON_TRUE) { diff --git a/application/window.c b/application/window.c index 26092cd..fe81481 100644 --- a/application/window.c +++ b/application/window.c @@ -150,7 +150,7 @@ static void playerEH(Widget widget, XtPointer data, XEvent *event, Boolean *disp if(!win->player || win->player->window == 0) return; - WindowPlayerWidgetEvent(win, event); + WindowHandlePlayerEvent(win, event); if(pass) { // redirect key events to the player window @@ -165,15 +165,35 @@ static void playerEH(Widget widget, XtPointer data, XEvent *event, Boolean *disp } } -void WindowPlayerWidgetEvent(MainWindow *win, XEvent *event) { +#define IGNORE_MOTION_THRESHOLD_MS 1000 +#define MOTION_POS_THRESHOLD_PIX 5 + +void WindowHandlePlayerEvent(MainWindow *win, XEvent *event) { + // event handler for intercepted player mouse events + // win->player is not NULL + int etype = event->type; if(etype == MotionNotify) { - + Time cur_motion_time = event->xmotion.time; + int x = event->xmotion.x; + int y = event->xmotion.y; + if(win->cursorhidden && cur_motion_time - win->player_event_time < IGNORE_MOTION_THRESHOLD_MS) { + int diff_x = abs(x - win->mouse_x_orig); + int diff_y = abs(y - win->mouse_y_orig); + if(diff_x > MOTION_POS_THRESHOLD_PIX || diff_y > MOTION_POS_THRESHOLD_PIX) { + WindowShowPlayerCursor(win); + } + } else { + win->mouse_x_orig = x; + win->mouse_y_orig = y; + } + win->player_event_time = cur_motion_time; + win->motion_playback_time = win->player->playback_time; } else if(etype == ButtonPress) { - + win->player_event_time = event->xbutton.time; } else if(etype == ButtonRelease) { - + win->player_event_time = event->xbutton.time; } } @@ -499,11 +519,12 @@ void WindowClosePlayer(MainWindow *win) { PlayerDestroy(win->player); } win->player = NULL; + WindowShowPlayerCursor(win); } void WindowHidePlayerCursor(MainWindow *win) { if(!win->cursorhidden && win->player && win->player->window != 0) { - //XDefineCursor(XtDisplay(win->player_widget), XtWindow(win->player_widget), blank_cursor); + XDefineCursor(XtDisplay(win->player_widget), XtWindow(win->player_widget), blank_cursor); win->cursorhidden = True; XFlush(XtDisplay(win->player_widget)); } diff --git a/application/window.h b/application/window.h index 4424273..7230515 100644 --- a/application/window.h +++ b/application/window.h @@ -57,6 +57,14 @@ typedef struct MainWindow { bool mbvisible; bool cursorhidden; bool buttongrab; + + Time player_event_time; + Time button_press_time; + double motion_playback_time; + int mouse_x; + int mouse_y; + int mouse_x_orig; + int mouse_y_orig; } MainWindow; MainWindow* WindowCreate(Display *dp); @@ -78,7 +86,7 @@ void WindowClosePlayer(MainWindow *win); void WindowHidePlayerCursor(MainWindow *win); void WindowShowPlayerCursor(MainWindow *win); -void WindowPlayerWidgetEvent(MainWindow *win, XEvent *event); +void WindowHandlePlayerEvent(MainWindow *win, XEvent *event); #ifdef __cplusplus } -- 1.8.3.1