awesomeWM / awesome

awesome window manager
https://awesomewm.org/
GNU General Public License v2.0
6.41k stars 597 forks source link

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

Open motorlatitude opened 4 years ago

motorlatitude commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

tried on my own electron app

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

psychon commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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

psychon commented 4 years ago

@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 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 #include +#include // Just because I want to printf() a uint32_t #include #include @@ -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 commented 4 years ago

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".