Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Electron frameless windows, using custom titlebars can not be dragged #3136

Open
motorlatitude opened this issue Jul 28, 2020 · 8 comments
Open

Comments

@motorlatitude
Copy link

Output of awesome --version:

awesome v4.3-858-g49a3859c8 (Too long)
 • Compiled against Lua 5.3.5 (running with Lua 5.3)
 • API level: 4
 • D-Bus support: yes
 • xcb-errors support: no
 • execinfo support: yes
 • xcb-randr version: 1.6
 • LGI version: 0.9.2
 • Transparency enabled: yes
 • Custom search paths: no

Issue:

Certain electron apps will use custom title bars over native ones, or the custom title bars fit more with the applications theming. Custom title bars use the -webkit-app-region: drag; CSS attribute to create draggable regions within the window. It is not currently possible to drag a window by using these draggable regions. They don't get recognised and as such these windows either have to use native title bars or resort to using the super + mouse drag combination.

Actual result:

The window can only be dragged using the super + mouse drag combination, not by the title bar, which is not ideal in floating mode. I personally like the custom title bar offered by VSCode but cannot move the window through it.

Expected result:

To drag a window by a native or custom title bar.

P.S. I'm not sure whether this is an issue with Awesome or Electron in this case.

@actionless
Copy link
Member

actionless commented Jul 29, 2020

P.S. I'm not sure whether this is an issue with Awesome or Electron in this case.

please try with Openbox, from my experience it's the least buggy (but still modern) WM in the world, so i always use it for double-checking any window-management-related quirks with the apps

@motorlatitude
Copy link
Author

So I quickly spun up an OpenBox VM and I used VSCode as a test and it was possible to drag the window using the custom title bar. Also quickly tried on my own electron app which also uses custom draggable regions and it also worked flawlessly on OpenBox.

@actionless
Copy link
Member

tried on my own electron app

if you can upload here the minimal reproductive example that would be useful

@psychon
Copy link
Member

psychon commented Jul 31, 2020

Random guess: Missing _NET_WM_MOVERESIZE support: https://specifications.freedesktop.org/wm-spec/wm-spec-1.3.html#idm45805408003200
And I have no idea how to "send" such a request through Lua.
(Also, the spec mentioning that it is broken and that there is a possible race condition inspires lots of trust...)

@Elv13
Copy link
Member

Elv13 commented Aug 8, 2020

And I have no idea how to "send" such a request through Lua.

That would be using request::geometry with a moveresize context and an hint table with x,y,width,height. If you can make a skeleton patch for the xcb side, then I can take care of the plumbing. Or would this be possible to implement it using the xproperty Lua API? I didn't test.

@motorlatitude
Copy link
Author

I went ahead and made a very simple electron app with draggable regions if needed for testing etc. Works in OpenBox.

@psychon
Copy link
Member

psychon commented Aug 9, 2020

@Elv13 Be sure to read the relevant part of EWMH:
https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm46035372584864

For testing: As soon as the WM announces support for _NET_WM_MOVERESIZE, GTK uses that. I "tested" the following patch with Gvim. When clicking and dragging in the toolbar (outside of any icons), it initiates a move. Dunno how to initiate a resize. (It also aborts the move when the button is released while still inside of that window, so perhaps that part can be tested via this.)

Patch to announce `_NET_WM_MOVERESIZE` support and only print requests that are received
diff --git a/common/atoms.list b/common/atoms.list
index 9cf41336e..d55777c32 100644
--- a/common/atoms.list
+++ b/common/atoms.list
@@ -67,3 +67,4 @@ AWESOME_SELECTION_ATOM
 INCR
 _XKB_RULES_NAMES
 _MOTIF_WM_HINTS
+_NET_WM_MOVERESIZE
diff --git a/ewmh.c b/ewmh.c
index ad7f51078..2dd01fefc 100644
--- a/ewmh.c
+++ b/ewmh.c
@@ -27,6 +27,7 @@
 
 #include <sys/types.h>
 #include <unistd.h>
+#include <inttypes.h> // Just because I want to printf() a uint32_t
 
 #include <xcb/xcb.h>
 #include <xcb/xcb_atom.h>
@@ -174,7 +175,8 @@ ewmh_init(void)
         _NET_WM_STATE_BELOW,
         _NET_WM_STATE_MODAL,
         _NET_WM_STATE_HIDDEN,
-        _NET_WM_STATE_DEMANDS_ATTENTION
+        _NET_WM_STATE_DEMANDS_ATTENTION,
+        _NET_WM_MOVERESIZE,
     };
     int i;
 
@@ -511,6 +513,75 @@ ewmh_process_client_message(xcb_client_message_event_t *ev)
             lua_pop(L, 1);
         }
     }
+    else if(ev->type == _NET_WM_MOVERESIZE)
+    {
+        if(ev->format == 32 && (c = client_getbywin(ev->window))) {
+            uint32_t x = ev->data.data32[0];
+            uint32_t y = ev->data.data32[1];
+            uint32_t dir = ev->data.data32[2];
+            uint32_t button = ev->data.data32[3];
+            uint32_t source = ev->data.data32[4];
+            printf("There was a button press at (%" PRIu32 ",%" PRIu32 ") (relative to the root window)\n", x, y);
+            printf("The direction is %" PRIu32 " and this is button %" PRIu32 " with source %" PRIu32 "\n",
+                    dir, button, source);
+            switch (dir) {
+            case 0:
+                puts("Direction is: resize topleft");
+                break;
+            case 1:
+                puts("Direction is: resize top");
+                break;
+            case 2:
+                puts("Direction is: resize topright");
+                break;
+            case 3:
+                puts("Direction is: resize right");
+                break;
+            case 4:
+                puts("Direction is: resize bottomright");
+                break;
+            case 5:
+                puts("Direction is: resize bottom");
+                break;
+            case 6:
+                puts("Direction is: resize bottomleft");
+                break;
+            case 7:
+                puts("Direction is: resize left");
+                break;
+            case 8:
+                puts("Direction is: move only");
+                break;
+            case 9:
+                puts("Direction is: resize initiated by keyboard (what does that even mean? should the mouse still be used? also: all(?) other fields are unused)");
+                break;
+            case 10:
+                puts("Direction is: move initiated by keyboard (what does that even mean? should the mouse still be used? also: all(?) other fields are unused)");
+                break;
+            case 11:
+                // No idea how to test this. Add a sleep() in AwesomeWM so that
+                // one can trigger this race at will?
+                puts("Direction is: cancel; there was a race and the user released the button before the WM reacted; stop the previously initiated operation");
+                break;
+            default:
+                puts("Direction is unknown");
+            }
+            switch (source) {
+            case 0:
+                puts("Source is: Some older EWMH version without source indication");
+                break;
+            case 1:
+                puts("Source is: Normal application");
+                break;
+            case 2:
+                puts("Source is: pager or something else that represents a direct user action");
+                break;
+            default:
+                puts("Source is: ???");
+            }
+            puts("");
+        }
+    }
 
     return 0;
 }

@psychon
Copy link
Member

psychon commented Aug 9, 2020

Also, since OpenBox was mentioned above: The relevant code seems to be: https://github.com/danakj/openbox/blob/9e8813e111cbe6c1088f6abbc771a29470f05fc2/openbox/event.c#L1476-L1511 and https://github.com/danakj/openbox/blob/9e8813e111cbe6c1088f6abbc771a29470f05fc2/openbox/moveresize.c#L177
"resize via keyboard" seems to be handled as "southeast" and "move via keyboard" just the same as "move".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants