]> git.eshelyaron.com Git - emacs.git/commitdiff
Rewrite desktop workarea computation to avoid too many calls to XSync
authorPo Lu <luangruo@yahoo.com>
Tue, 29 Mar 2022 10:31:24 +0000 (18:31 +0800)
committerPo Lu <luangruo@yahoo.com>
Tue, 29 Mar 2022 10:33:00 +0000 (18:33 +0800)
* src/xfns.c (x_get_net_workarea): Rewrite using XCB without
using long_offset and long_length, since the data transfer is
usually negligible compared to the roundtrip delay.

src/xfns.c

index 534fb7c544ea16619c71ad55a39683a4d58e3e42..37e0628464fa058ad7ea1eee495979172ecd9149 100644 (file)
@@ -5459,6 +5459,7 @@ On MS Windows, this just returns nil.  */)
 static bool
 x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle *rect)
 {
+#ifndef USE_XCB
   Display *dpy = dpyinfo->display;
   long offset, max_len;
   Atom target_type, actual_type;
@@ -5512,6 +5513,69 @@ x_get_net_workarea (struct x_display_info *dpyinfo, XRectangle *rect)
   x_uncatch_errors ();
 
   return result;
+#else
+  xcb_get_property_cookie_t current_desktop_cookie;
+  xcb_get_property_cookie_t workarea_cookie;
+  xcb_get_property_reply_t *reply;
+  xcb_generic_error_t *error;
+  bool rc;
+  uint32_t current_workspace, *values;
+
+  current_desktop_cookie
+    = xcb_get_property (dpyinfo->xcb_connection, 0,
+                       (xcb_window_t) dpyinfo->root_window,
+                       (xcb_atom_t) dpyinfo->Xatom_net_current_desktop,
+                       XCB_ATOM_CARDINAL, 0, 1);
+
+  workarea_cookie
+    = xcb_get_property (dpyinfo->xcb_connection, 0,
+                       (xcb_window_t) dpyinfo->root_window,
+                       (xcb_atom_t) dpyinfo->Xatom_net_workarea,
+                       XCB_ATOM_CARDINAL, 0, UINT32_MAX);
+
+  reply = xcb_get_property_reply (dpyinfo->xcb_connection,
+                                 current_desktop_cookie, &error);
+  rc = true;
+
+  if (!reply)
+    free (error), rc = false;
+  else
+    {
+      if (xcb_get_property_value_length (reply) != 4
+         || reply->type != XCB_ATOM_CARDINAL || reply->format != 32)
+       rc = false;
+      else
+       current_workspace = *(uint32_t *) xcb_get_property_value (reply);
+
+      free (reply);
+    }
+
+  reply = xcb_get_property_reply (dpyinfo->xcb_connection,
+                                 workarea_cookie, &error);
+
+  if (!reply)
+    free (error), rc = false;
+  else
+    {
+      if (rc && reply->type == XCB_ATOM_CARDINAL && reply->format == 32
+         && (xcb_get_property_value_length (reply) / sizeof (uint32_t)
+             >= current_workspace + 4))
+       {
+         values = xcb_get_property_value (reply);
+
+         rect->x = values[current_workspace];
+         rect->y = values[current_workspace + 1];
+         rect->width = values[current_workspace + 2];
+         rect->height = values[current_workspace + 3];
+       }
+      else
+       rc = false;
+
+      free (reply);
+    }
+
+  return rc;
+#endif
 }
 #endif /* !(USE_GTK && HAVE_GTK3) */