add cursor autohide
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 16 Jan 2022 10:18:46 +0000 (11:18 +0100)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 16 Jan 2022 10:18:46 +0000 (11:18 +0100)
application/main.c
application/player.c
application/window.c
application/window.h

index 43d6c05..028a163 100644 (file)
@@ -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);
         }
index 6cdba87..4764e98 100644 (file)
@@ -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) {
index 26092cd..fe81481 100644 (file)
@@ -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));
     }
index 4424273..7230515 100644 (file)
@@ -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
 }