[vlc-commits] [Git][videolan/vlc][master] 10 commits: xcb/window: pass event mask to OpenCommon()

Rémi Denis-Courmont (@Courmisch) gitlab at videolan.org
Tue May 31 18:39:53 UTC 2022



Rémi Denis-Courmont pushed to branch master at VideoLAN / VLC


Commits:
4ef015d9 by Rémi Denis-Courmont at 2022-05-31T17:31:02+00:00
xcb/window: pass event mask to OpenCommon()

- - - - -
2d439b25 by Rémi Denis-Courmont at 2022-05-31T17:31:02+00:00
xcb/window: only subscribe to keyboard events if enabled

- - - - -
4b5880da by Rémi Denis-Courmont at 2022-05-31T17:31:02+00:00
xcb/window: wait for window to be mapped

The user of the window typically uses a different connection to the X11
than the window module. The window must be mapped before the user tries
anything with it. On a different connection a mere `xcb_flush()` is not
sufficient, as it does not guarantee that the X11 server served the
request.

The current code relies on the fact that the window map request will
necessarily have been processed before the pointer query reply is
received. But the pointer query will be (re)moved, so it cannot be
relied on any longer.

- - - - -
937130ad by Rémi Denis-Courmont at 2022-05-31T17:31:02+00:00
xcb/window: add a local variable

No functional changes.

- - - - -
8775c91a by Rémi Denis-Courmont at 2022-05-31T17:31:02+00:00
xcb/window: get mouse position once, asynchronously

- - - - -
11bce8cb by Rémi Denis-Courmont at 2022-05-31T17:31:02+00:00
xcb/window: get initial size asynchronously

- - - - -
cd8fe1ba by Rémi Denis-Courmont at 2022-05-31T17:31:02+00:00
xcb/window: wait for known size when enabling

- - - - -
0a2f9774 by Rémi Denis-Courmont at 2022-05-31T17:31:02+00:00
contrib: xcb: require XCB 1.8 or later

- - - - -
dbf4f24a by Rémi Denis-Courmont at 2022-05-31T17:31:02+00:00
configure: bump XCB version requirement to 1.8

This is over 11 years old.

- - - - -
549c6c72 by Rémi Denis-Courmont at 2022-05-31T17:31:02+00:00
xcb/window: process interleaved events

If an event occur between a request and a reponse, it needs to be
processed before the response, to avoid an inversion.

- - - - -


3 changed files:

- configure.ac
- contrib/src/xcb/rules.mak
- modules/video_output/xcb/window.c


Changes:

=====================================
configure.ac
=====================================
@@ -3194,7 +3194,7 @@ AS_IF([test "${enable_xcb}" != "no"], [
   xcb_err=""
 
   dnl libxcb
-  PKG_CHECK_MODULES([XCB], [xcb >= 1.6],, [
+  PKG_CHECK_MODULES([XCB], [xcb >= 1.8],, [
     xcb_err="$xcb_err ${XCB_PKG_ERRORS}."])
   PKG_CHECK_MODULES([XCB_COMPOSITE], [xcb-composite],, [
     xcb_err="$xcb_err ${XCB_COMPOSITE_PKG_ERRORS}."])


=====================================
contrib/src/xcb/rules.mak
=====================================
@@ -9,7 +9,7 @@ PKGS += xcb
 endif
 endif
 
-ifeq ($(call need_pkg,"xcb >= 1.6 xcb-shm xcb-composite xcb-xv >= 1.1.90.1"),)
+ifeq ($(call need_pkg,"xcb >= 1.8 xcb-shm xcb-composite xcb-xv >= 1.1.90.1"),)
 # xcb-randr >= 1.3 is not that useful
 PKGS_FOUND += xcb
 endif


=====================================
modules/video_output/xcb/window.c
=====================================
@@ -53,6 +53,7 @@ typedef struct
 {
     xcb_connection_t *conn;
     vlc_thread_t thread;
+    vlc_latch_t ready;
 
     xcb_window_t root;
     xcb_atom_t wm_state;
@@ -330,13 +331,37 @@ static void *Thread (void *data)
         .fd = xcb_get_file_descriptor(conn),
         .events = POLLIN,
     };
+    xcb_window_t window = wnd->handle.xid;
     xcb_cursor_t cursor = CursorCreate(conn, p_sys->root); /* blank cursor */
     vlc_tick_t lifetime = VLC_TICK_FROM_MS( var_InheritInteger(wnd, "mouse-hide-timeout") );
     vlc_tick_t deadline = VLC_TICK_MAX;
+    xcb_generic_event_t *ev;
 
     if (ufd.fd == -1)
         return NULL;
 
+    /* Report initial pointer position. */
+    xcb_query_pointer_cookie_t qpc = xcb_query_pointer(conn, window);
+    /* Report initial window size (for the embedded case). */
+    xcb_get_geometry_cookie_t ggc = xcb_get_geometry(conn, window);
+
+    xcb_query_pointer_reply_t *qpr = xcb_query_pointer_reply(conn, qpc, NULL);
+    if (qpr != NULL) {
+        while ((ev = xcb_poll_for_queued_event(conn)) != NULL)
+            ProcessEvent(wnd, ev);
+        vlc_window_ReportMouseMoved(wnd, qpr->win_x, qpr->win_y);
+        free(qpr);
+    }
+
+    xcb_get_geometry_reply_t *geo = xcb_get_geometry_reply(conn, ggc, NULL);
+    if (geo != NULL) {
+        while ((ev = xcb_poll_for_queued_event(conn)) != NULL)
+            ProcessEvent(wnd, ev);
+        vlc_window_ReportSize(wnd, geo->width, geo->height);
+        free(geo);
+    }
+    vlc_latch_count_down(&p_sys->ready, 1);
+
     for (;;)
     {
         int timeout = -1;
@@ -353,14 +378,12 @@ static void *Thread (void *data)
 
         if (val == 0)
         {   /* timeout: hide cursor */
-            xcb_change_window_attributes(conn, wnd->handle.xid,
-                                         XCB_CW_CURSOR, &cursor);
+            xcb_change_window_attributes(conn, window, XCB_CW_CURSOR, &cursor);
             xcb_flush(conn);
             deadline = VLC_TICK_MAX;
         }
         else
         {
-            xcb_generic_event_t *ev;
             bool show_cursor = false;
 
             while ((ev = xcb_poll_for_event (conn)) != NULL)
@@ -368,8 +391,7 @@ static void *Thread (void *data)
 
             if (show_cursor)
             {
-                xcb_change_window_attributes(conn, wnd->handle.xid,
-                                             XCB_CW_CURSOR,
+                xcb_change_window_attributes(conn, window, XCB_CW_CURSOR,
                                              &(uint32_t){ XCB_CURSOR_NONE });
                 xcb_flush(conn);
                 deadline = vlc_tick_now() + lifetime;
@@ -538,6 +560,7 @@ static int Enable(vlc_window_t *wnd, const vlc_window_cfg_t *restrict cfg)
     vout_window_sys_t *sys = wnd->sys;
     xcb_connection_t *conn = sys->conn;
     xcb_window_t window = wnd->handle.xid;
+    xcb_void_cookie_t ck;
 
     /* Set initial window state */
     if (cfg->is_decorated)
@@ -552,21 +575,9 @@ static int Enable(vlc_window_t *wnd, const vlc_window_cfg_t *restrict cfg)
     }
 
     /* Make the window visible */
-    xcb_map_window(conn, window);
-
-    /* Report initial pointer position.
-     * This will implicitly flush the XCB connection so that the window gets
-     * mapped by the display server shortly.
-     */
-    xcb_query_pointer_cookie_t qpc = xcb_query_pointer(conn, window);
-    xcb_query_pointer_reply_t *pr = xcb_query_pointer_reply(conn, qpc, NULL);
-
-    if (pr != NULL)
-    {
-        vlc_window_ReportMouseMoved(wnd, pr->win_x, pr->win_y);
-        free(pr);
-    }
-
+    ck = xcb_map_window_checked(conn, window);
+    free(xcb_request_check(conn, ck));
+    vlc_latch_wait(&sys->ready);
     return VLC_SUCCESS;
 }
 
@@ -591,9 +602,8 @@ static const struct vlc_window_operations ops = {
     .set_state = SetState,
 };
 
-static int OpenCommon(vlc_window_t *wnd, char *display,
-                      xcb_connection_t *conn,
-                      xcb_window_t root, xcb_window_t window)
+static int OpenCommon(vlc_window_t *wnd, char *display, xcb_connection_t *conn,
+                      xcb_window_t root, xcb_window_t window, uint32_t events)
 {
     vout_window_sys_t *sys = vlc_obj_malloc(VLC_OBJECT(wnd), sizeof (*sys));
     if (sys == NULL)
@@ -609,7 +619,7 @@ static int OpenCommon(vlc_window_t *wnd, char *display,
     sys->root = root;
 
 #ifdef HAVE_XKBCOMMON
-    if (var_InheritBool(wnd, "keyboard-events"))
+    if (events & XCB_EVENT_MASK_KEY_PRESS)
         InitKeyboardExtension(wnd);
     else
         sys->xkb.ctx = NULL;
@@ -680,6 +690,7 @@ static int OpenCommon(vlc_window_t *wnd, char *display,
     sys->wm_state_fullscreen = get_atom(conn, wm_state_fs_ck);
     sys->motif_wm_hints = get_atom(conn, motif_wm_hints_ck);
 
+    vlc_latch_init(&sys->ready, 1);
     /* Create the event thread. It will dequeue all events, so any checked
      * request from this thread must be completed at this point. */
     if (vlc_clone(&sys->thread, Thread, wnd))
@@ -733,10 +744,11 @@ static int Open(vlc_window_t *wnd)
         /* XCB_CW_BACK_PIXEL */
         scr->black_pixel,
         /* XCB_CW_EVENT_MASK */
-        XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_POINTER_MOTION |
-        XCB_EVENT_MASK_STRUCTURE_NOTIFY,
+        XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_STRUCTURE_NOTIFY,
     };
 
+    if (var_InheritBool(wnd, "keyboard-events"))
+        values[1] |= XCB_EVENT_MASK_KEY_PRESS;
     if (var_InheritBool(wnd, "mouse-events"))
         values[1] |= XCB_EVENT_MASK_BUTTON_PRESS
                    | XCB_EVENT_MASK_BUTTON_RELEASE;
@@ -754,7 +766,7 @@ static int Open(vlc_window_t *wnd)
         goto error;
     }
 
-    ret = OpenCommon(wnd, display, conn, scr->root, window);
+    ret = OpenCommon(wnd, display, conn, scr->root, window, values[1]);
     if (ret != VLC_SUCCESS)
         goto error;
 
@@ -912,20 +924,18 @@ static int EmOpen (vlc_window_t *wnd)
         goto error;
     }
     root = geo->root;
-    /* FIXME: racy - compare seq.no.with configure event */
-    vlc_window_ReportSize(wnd, geo->width, geo->height);
     free (geo);
 
     /* Try to subscribe to keyboard and mouse events (only one X11 client can
      * subscribe to input events, so this can fail). */
-    value |= XCB_EVENT_MASK_KEY_PRESS;
-
+    if (var_InheritBool(wnd, "keyboard-events"))
+        value |= XCB_EVENT_MASK_KEY_PRESS;
     if (var_InheritBool(wnd, "mouse-events"))
         value |= XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE;
 
     xcb_change_window_attributes(conn, window, XCB_CW_EVENT_MASK, &value);
 
-    ret = OpenCommon(wnd, NULL, conn, root, window);
+    ret = OpenCommon(wnd, NULL, conn, root, window, value);
     if (ret != VLC_SUCCESS)
         goto error;
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/1430071b092c2cdf3c4fc7c1c598240c9d54b53a...549c6c725a31ea873d3683399bf279c00089ae83

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/1430071b092c2cdf3c4fc7c1c598240c9d54b53a...549c6c725a31ea873d3683399bf279c00089ae83
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list