ssokolow / quicktile

Adds window-tiling hotkeys to any X11 desktop. (An analogue to WinSplit Revolution for people who don't want to use Compiz Grid)
https://ssokolow.com/quicktile/
GNU General Public License v2.0
878 stars 79 forks source link

Overlapping windows when positioning vertically on Ubuntu 20.04 #117

Closed SimonEggert closed 1 year ago

SimonEggert commented 4 years ago

At first I want to thank you for this great tool! Using both OS X and Ubuntu I was looking for a solution that was similar to what Rectangle does on Mac and found it with quicktile.

I recently upgraded to Ubuntu 20.04 and am facing an issue where vertically positioned windows would overlap (e.g. two windows with 50% height, one at the top and the other at the bottom) when using the dock at the bottom. This is also true for a left-positioned dock and horizontal side-by-side windows. In another issue you mention the dock not being respected properly when quicktile starts before the dock has occupied its space, so I tried to investigate in that direction.

This is the debug output from the scenario mentioned above:

DEBUG: Loaded monitor geometry: [Rectangle(x=0, y=0, width=2560, height=1440)]
DEBUG: Usable desktop region calculated as: Region(<Monitors=[Rectangle(x=0, y=0, width=2560, height=1440)], Struts=[]>)

DEBUG: Received keybind: <Primary><Alt><Mod2>KP_Down
DEBUG: Executing command 'bottom' with arguments (), {}
DEBUG: Loaded monitor geometry: [Rectangle(x=0, y=0, width=2560, height=1440)]
DEBUG: Usable desktop region calculated as: Region(<Monitors=[Rectangle(x=0, y=0, width=2560, height=1440)], Struts=[]>)
DEBUG: Operating on window <Wnck.Window object at 0x7f0f1459b480 (WnckWindow at 0x2cf0460)> with title "fish /home/simon" and geometry Rectangle(x=50, y=27, width=1280, height=1345)
DEBUG:  Window is on monitor 0, which has geometry Rectangle(x=0, y=0, width=2560, height=1440)
DEBUG: Selected preset sequence:
    ((0.0, 0.5, 1.0, 0.5), (0.334, 0.5, 0.333, 0.5), (0.166, 0.5, 0.667, 0.5))
DEBUG: Selected preset sequence resolves to these monitor-relative pixel dimensions:
    [Rectangle(x=0, y=720, width=2560, height=720), Rectangle(x=855, y=720, width=852, height=720), Rectangle(x=424, y=720, width=1707, height=720)]
DEBUG: Restarting cycle position sequence
DEBUG: Target preset is Rectangle(x=0, y=720, width=2560, height=720) relative to monitor <Gdk.Rectangle object at 0x7f0f14597220 (GdkRectangle at 0x2cf98a0)>
DEBUG: Calling reposition() with default gravity and dimensions Rectangle(x=0, y=720, width=2560, height=720)
DEBUG:  Window is on monitor 0, which has geometry Rectangle(x=0, y=0, width=2560, height=1440)
DEBUG:  Repositioning to Rectangle(x=0, y=720, width=2560, height=720))

DEBUG: Received keybind: <Primary><Alt><Mod2>KP_Up
DEBUG: Executing command 'top' with arguments (), {}
DEBUG: Loaded monitor geometry: [Rectangle(x=0, y=0, width=2560, height=1440)]
DEBUG: Usable desktop region calculated as: Region(<Monitors=[Rectangle(x=0, y=0, width=2560, height=1440)], Struts=[]>)
DEBUG: Operating on window <Wnck.Window object at 0x7f0f1459ee80 (WnckWindow at 0x2cf0340)> with title "quicktile /home/simon" and geometry Rectangle(x=0, y=27, width=2560, height=1345)
DEBUG:  Window is on monitor 0, which has geometry Rectangle(x=0, y=0, width=2560, height=1440)
DEBUG: Selected preset sequence:
    ((0.0, 0.0, 1.0, 0.5), (0.334, 0.0, 0.333, 0.5), (0.166, 0.0, 0.667, 0.5))
DEBUG: Selected preset sequence resolves to these monitor-relative pixel dimensions:
    [Rectangle(x=0, y=0, width=2560, height=720), Rectangle(x=855, y=0, width=852, height=720), Rectangle(x=424, y=0, width=1707, height=720)]
DEBUG: Got saved cycle position: 0, 0
DEBUG: Target preset is Rectangle(x=0, y=0, width=2560, height=720) relative to monitor <Gdk.Rectangle object at 0x7f0f14597340 (GdkRectangle at 0x2cf9f00)>
DEBUG: Calling reposition() with default gravity and dimensions Rectangle(x=0, y=0, width=2560, height=720)
DEBUG:  Window is on monitor 0, which has geometry Rectangle(x=0, y=0, width=2560, height=1440)
DEBUG:  Repositioning to Rectangle(x=0, y=0, width=2560, height=720))

Surprisingly (or maybe not?) I am not getting any DEBUG: Gathered _NET_WM_STRUT_PARTIAL whatsoever. So my guess would be that no struts result in quicktile handling the whole resolution as a basis for its calculations. Is there a way to dig deeper into this and see if Ubuntu actually sets these things correctly? I don't have any experience with window management, but I'll be glad to provide further information if needed.

As a sidenote: I was also able to reproduce this issue on my 1080p-notebook in case that's helpful for debugging.

ssokolow commented 4 years ago

I think it's a GNOME Shell bug. You're not the first person to report this problem with QuickTile receiving no strut reservations.

To remedy it, I might have no other option than to prioritize the config file rewrite that allows hierarchical data and then add an option that allows manually specifying rectangles to be injected into the list of harvested strut data before doing usable region calculations.

If you want to double-check that a strut-harvesting bug didn't creep into QuickTile, there are two other ways I can suggest to query struts:

  1. The initial version of the code QuickTile uses for querying _NET_WM_STRUT_PARTIAL is available as a standalone script on this StackOverflow answer. It doesn't query _NET_WM_STRUT if a window neglects to set _NET_WM_STRUT_PARTIAL, but it should check all windows on the system in a single convenient command.

  2. You can run xprop | grep STRUT and then click the problem panel to see if it's setting struts.

    On my system, doing that with a Plasma panel produces output like this:

    _NET_WM_STRUT(CARDINAL) = 0, 0, 0, 36
    _NET_WM_STRUT_PARTIAL(CARDINAL) = 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 1280, 3199
SimonEggert commented 4 years ago

Thank you for your response!

Manually adding the dock's dimensions sounds like a solution you wouldn't really want to be forced to support, but if you find the time to implement something like this, I'll be happy to test it.

I double-checked the struts with both of your suggested methods and neither of them gave me a result, so I guess it is indeed a bug outside of QuickTile. Aren't these kinds of things standardized in some way to ensure you've got something to rely on when doing window management and calculations?

I hope to find the time to check an older version of Ubuntu, as I have just started using QuickTile and am unsure if the problem is occurring there as well.

ssokolow commented 4 years ago

Aren't these kinds of things standardized in some way to ensure you've got something to rely on when doing window management and calculations?

That is the standard.

_NET_WM_STRUT_PARTIAL

_NET_WM_STRUT_PARTIAL, left, right, top, bottom, left_start_y, left_end_y,
right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x,
bottom_end_x,CARDINAL[12]/32

This property MUST be set by the Client if the window is to reserve space at the edge of the screen.

As far as I can guess, since GNOME Shell is both compositor and desktop panel provider, and their primary target is Wayland now, they just stopped caring about complying with X11 standards that have no Wayland equivalent because, by design, tools like QuickTile (ie. applications which manipulate other applications' windows) are impossible on Wayland for security reasons.

Manually adding the dock's dimensions sounds like a solution you wouldn't really want to be forced to support, but if you find the time to implement something like this, I'll be happy to test it.

Point.

Maybe I should just add a FAQ entry instructing people to query the geometry of their panel using something like wmctrl -l -G and then force it to comply with standards by manually setting _NET_WM_STRUT_PARTIAL on the panel using xprop -set.

SimonEggert commented 4 years ago

Maybe I should just add a FAQ entry instructing people to query the geometry of their panel using something like wmctrl -l -G and then force it to comply with standards by manually setting _NET_WM_STRUT_PARTIAL on the panel using xprop -set

That would be a big help for people like me who've never looked into these things in depth.

Experimenting with wmctrl I found that wmctrl -d would give me the correct workspace size (e.g. 1920x985 on a 1920x1080 screen), but wmctrl -l -G does only list actual windows and the dock not there.

Another thing I don't quite understand is why it works correctly and respects the dock's height when using left, center or right positioning. The windows in those situations do not get cut off at the bottom where the dock is placed.

I might as well be changing over to another Ubuntu flavor as I am not really bound to GNOME by any means and just set up the systems a few days ago. I just reproduced the issue with Ubuntu 18.04.4, so I guess the behavior is not going to change anywhere in the near future.

ssokolow commented 4 years ago

Experimenting with wmctrl I found that wmctrl -d would give me the correct workspace size (e.g. 1920x985 on a 1920x1080 screen)

It's probably using _NET_WORKAREA, which I used to use, but it fundamentally assumes a rectangular usable region, which breaks badly in most multi-monitor setups because it can only describe a rectangle. (It only works properly if your monitors and panels are uniform enough that the usable region is rectangular.)

but wmctrl -l -G does only list actual windows and the dock not there.

Hmm. What do you get if you run xprop (no arguments) and click on the panel?

Another thing I don't quite understand is why it works correctly and respects the dock's height when using left, center or right positioning. The windows in those situations do not get cut off at the bottom where the dock is placed.

QuickTile can't force window positioning... just request it. The window manager then modifies the requested geometry to apply rules like "only a human, moving a window directly, may position it partly off-screen".

Normally, the window manager will prefer to move the requested rectangle to be entirely within the usable region of the desktop without altering its size, resulting in overlap. However, for a full-height preset, the window manager will usually be programmed to assume that allowing the window to extend off screen is the greater of two evils and shrink the window once it finds that merely moving it can't satisfy the rules.

Thus, QuickTile spends an inordinate amount of code on anticipating how the WM will modify the geometry it requests, so it can pre-emptively compensate.

SimonEggert commented 4 years ago

QuickTile can't force window positioning... just request it.

Thank you for the detailed explanation! I am slowly starting to understand how the different layers work together.

xprop on the dock gives me XdndProxy(WINDOW): window id # 0xa00011. This is the same for both the top status bar and the dock at the bottom by the way.

The dock is 68px high, the status bar has 27px height, so I tried to set _NET_WM_STRUT_PARTIAL manually to accommodate for these sizes by running xprop -id 0xa00011 -f _NET_WM_STRUT_PARTIAL 32c -set _NET_WM_STRUT_PARTIAL 0,0,27,68,0,0,0,0,0,50,1023.

I confirmed that the value was correctly added to the window by running xprop -id 0xa00011. After that I restarted quicktile in debug mode, but still did not get any output regarding struts. Is this the correct way you suggested earlier by this?

Maybe I should just add a FAQ entry instructing people to query the geometry of their panel using something like wmctrl -l -G and then force it to comply with standards by manually setting _NET_WM_STRUT_PARTIAL on the panel using xprop -set.

ssokolow commented 4 years ago

Is this the correct way you suggested earlier by this?

I can't double-check that right now (I had one of my sites break late last night and need to prioritize figuring out how to fix it) but, If xprop gave you XdndProxy(WINDOW): window id # 0xa00011 for both panels, then I can only think of two possibilities:

  1. GNOME Shell is engaging in funny business
  2. The panels are actually drawn as part of the desktop. (See if you get the same window ID by clicking bare desktop)

Is that line all you got? I'd expected something like this output from my Plasma panel:

``` _NET_WM_STRUT(CARDINAL) = 0, 0, 0, 36 _NET_WM_STRUT_PARTIAL(CARDINAL) = 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 1280, 3199 _KDE_NET_WM_ACTIVITIES(STRING) = "00000000-0000-0000-0000-000000000000" _NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_CHANGE_DESKTOP WM_STATE(WM_STATE): window state: Normal icon window: 0x0 _NET_WM_STATE(ATOM) = _NET_WM_USER_TIME(CARDINAL) = 3377925444 _NET_WM_DESKTOP(CARDINAL) = 4294967295 _KDE_NET_WM_BLUR_BEHIND_REGION(CARDINAL) = _KDE_NET_WM_USER_CREATION_TIME(CARDINAL) = 2513008873 _KDE_SLIDE(_KDE_SLIDE) = 0xffffffff, 0x3 _KDE_NET_WM_SHADOW(CARDINAL) = 299892765, 299892767, 299892768, 299892769, 299892770, 299892771, 299892772, 299892773, 8, 8, 8, 8 _NET_WM_ICON(CARDINAL) = Icon (16 x 16): ░ ░▒ ░ ░ ░ ░ ░ ░░░░ ░░░░░ ░░░░░ ░ ░░░░░ ░ ░ ░░ ░ ░ ░░░░ ░ ░░░ ░░░ ░░░ Icon (22 x 22): ░░ ░░ ░░▒ ░░░ ░ ░ ░░░ ░░ ░░ ░ ░░ ░ ░░░ ░ ░░░░ ░░░░░░░ ░░░░░░ ░ ░░░░░░ ░░ ░░░░░░ ░░ ░░ ░░░ ░ ░ ░░░░░░ ░ ░░░░ ░ ░░░░░ ░░ ░░░░ ░░░░░░░░ Icon (32 x 32): ░ ░░▒░ ░░▒ ▒░▒▒ ░▒░▒ ░▒▒░ ▒▒░ ░░░ ░░▒▒ ▒▒░ ░ ░░ ░ ░░░ ░ ░░░░ ░ ░░░░░ ░ ░░░░ ░ ░░ ░░░░░ ░ ░░░░░░░░ ░░ ░░░░░░░░░ ░░ ░░░░░░░░░ ░░░░░░░░ ░ ░░░░░░░░░ ░ ░░░░░░░░░░ ░ ░░░ ░░░░░░ ░ ░░░ ░ ░░ ░░░░ ░ ░░░ ░░░░░░ ░ ░░ ░░░░░░░░ ░░ ░░░░░░░ ░░ ░░░░░░░ ░░░ ░░░░░▒ ░░░░ ░░░░░ ░░░░░░░░░░░░░ ░░░░░░ Icon (48 x 48): ░ ░░░ ░▒░▒ ░░░░▒ ▒░▒▒▒ ░░░▒▓ ░▒░░▒▓ ▒▒░░▒ ░ ▒▒░▒▒ ░▒▒▒░ ░░░░░ ▒▒░ ░ ░░░▒▒ ▒▒░▒▒ ░ ░▒▒▒░ ░ ░░░ ░ ░ ░░ ░ ░ ░ ░░░░ ░ ░░░░ ░░ ░░░░ ▒ ░░░░░ ░░ ░░░░░░ ▒░ ░░░░░░ ░ ░░ ░░░░░░░ ░ ░░ ░░░░░░░░ ░░ ▒░ ░░░░░░░░░ ░ ░░░░░░░░░░░░ ░░ ░░░░░░░░░░░░░ ░░ ░░░░░░░░░░░░░░ ░░░ ░░░░ ░░░░░░░░░░░░░░ ░░░░░░░░░ ░░ ░░░░░░░░░░░░░░ ░░ ░░░░░░░░░░░░░░░ ░░ ░░░░░░░░░░░░░░ ░ ▒░░░░░░░░░░░░░░ ░░ ░░░ ░ ░░░░ ░░ ░░ ▒░░ ░░░░░░░ ░░ ░░░ ░░░░░░░ ░░ ░░░ ░░░░░░░░░ ░░ ░░░ ░░░░░░░░░░░ ░░░░ ░░░░░░░░░░ ░░░░ ░░░░░░░░░░ ░░░░ ░░░░░░░░░▒ ░░░░ ░░░░░░░░░░ ░░░░░ ░░░░░░░░▒ ░░░░░ ░░░░░░░▒ ░░░░░░░ ░░░░░░░▒░ ░░░░░░░░░░░░░░░▒░ ░░░░░░░░░░░ Icon (64 x 64): ░░ ░▒░░░ ▒▒░░▒ ░░░░▒▒ ░▒░░▒▒▓ ░ ░░░▒▓ ▒░ ░▒▒▓ ▒░░░░▒▓ ▒▒░░░▒▓ ▒▒▒░░▒▒ ░░░ ░▓▒░░▒▒ ▒▒▒▒▒░ ░░░░░░ ▒▒▒▒▒░ ▒▒▒░ ░░░░▒▒ ░░░ ░░░▒▒▒▒░ ░ ░▒▒░░▒▒░ ░ ▒▒▒▒▒▒ ░ ▒▒▒▒ ░░ ░ ░ ░ ░ ░ ░░ ░░░░░ ░░ ░░░░░ ▒ ░░░░░░ ░░ ░░░░░░ ░▒ ░░░░░░░ ▒░ ░░░░░░ ░▒░ ░░░░░░░ ▒░ ░░░░░░░░░ ▒░ ░░░░░░░░░ ░ ░░░ ░░░░░░░░░░ ░░ ▒░ ░░░░░░░░░░ ░░ ▒░ ░░░░░░░░░░░ ▒░ ░░░ ░░░░░░░░░░░░ ░▒ ░░░ ░░░░░░░░░░░░░ ░░░ ░░░░░░░░░░░░░░░░░ ░▒░ ▒░░░░░░░░░░░░░░░░ ░░▒░ ▒░░░░░░░░░░░░░░░░ ░░░░░░ ░░░░░░░░░░░ ▒░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░ ░░ ▒░░░░░░░░░░░░░░░░░ ░░ ▒░░░░░░░░░░░░░░░░░ ░ ░░░░░░░░░░░░░░░░░░░ ░░ ░░░░░░░░░░░░░░░░░░░ ░░ ░░░░░░░░░░░░░░░░░░░░ ░░ ▒░░░ ░░░░░░░░░░ ░░ ▒░░░ ░░ ░░░░ ░░░░░░ ░░ ▒░░░ ░░░░░░░░ ░░ ░░░░ ░░░░░░░░░░ ░░ ▒░░░ ░░░░░░░░░░░ ░░ ░░░░ ░░░░░░░░░░░░ ░░ ░░░░ ░░░░░░░░░░░░░░▒ ▒░░░ ░░░░░░░░░░░░░▒ ░▒░░░ ░░░░░░░░░░░░░░ ░▒░░░ ░░░░░░░░░░░░▒ ░▒░░░ ░░░░░░░░░░░░▒ ░▒░░░ ░░░░░░░░░░░░▒ ░▒░░░░ ░░░░░░░░░░░▒░ ░░░░░ ░░░░░░░░░░▒▒ ░▒░░░░ ░░░░░░░░░▒▒ ░░░░░░░ ░░░░░░░░░▒░ ░▒░░░░░░░ ░░░░░░░░░░▒▒ ░░░░░░░░░░░░░░░░░░░▒▒░░ ░░░░░░░░░░░▒▒▒░░ Icon (128 x 128): ░░ ▒▒▒▒▒▓▒ ▒▒▓▓▒ ░▓░░░░░░▒▓ ▒▓▒░░░▒▓▒ ░▒░░░░░░░░▒▓ ▒▓░░░░░░░▓▒ ▒░ ░░░░░░░▒▓▒ ░▓░░░░░░▒▒▒▓▒ ░░ ░░░░░▒▒▒▒▓ ▓▒░░░░░▒▒▒▒▓▓ ░░ ░░░░░▒▒▒▓▓ ░▓▒ ░░░▒▒▒▒▓▓░ ▒▒░░░░░░░░▒▒▒▓░ ░▓▒ ░░░▒▒▒▓▓▓▒ ▒▓▒▒░░░░░░▒▒▒▓░ ░▓▒░░░░░░▒▒▒▓▓▒ ░▓▒▒▒░░░░░░▒▓▓ ░░░░ ░▓▓▒▒░░░░░▒▒▓▓░ ▓▓▒▒▒░░░░▒▒▓▒ ▒▒▒▒▒▒░ ░░░ ░ ▓▓▒▒▒░░░░▒▒▓▓ ░▓▓▒▒▒▒▒▒▒▓▓ ░▒░░░░░░▒▒ ░░ ░ ▒▓▒▒▒▒░░░▒▒▓▒ ▒▓▓▓▒▒▒▒▓▓░ ░▒░░░░░░░░▒▒ ░░ ░ ▒▒▒▒▒▒▒▒▒▒▒ ░▓▓▓▓▓▓▒░ ▒░░░░░░░░░▒▓░ ░░ ░ ▒▒▒▒▒▒▒▒▒ ░▒▒▒░ ░░ ░░░░▒▒▒▒▒▒ ░ ░ ░▒▒▒▒▒░ ▒░ ░▒▒▒▒▒▒▒▓▓ ░░ ░ ▒░░░░▒░▒▒▒▒▒▒▒ ░ ░ ▒▒░░▒▒░░░▒▒▒▒▒ ░░ ░ ░▒▒▒▒▒░░░▒▒▒▒▒ ░░ ░▒▒▒▒▒▒░▒▒▒▒▒░ ░░ ░ ░▒▒▒▒▒▒▒▒▒▒▒ ░░ ░ ░▒▒▒▒▒▒▒▒▒ ░░ ░ ░░▒▒▒▒▒░ ░░░ ░ ░░░░░ ░░░ ░ ░░░ ░ ░░░ ░ ░░░ ░ ░░░ ░░ ░░░ ░ ░ ░░░ ░░░ ░ ░░░░ ░░░░░ ░░ ░▒░ ░░░░░░░░░░ ░▒░ ░░░░░░░░░░░ ░▒░░ ░░░░░░░░░░░░ ░▒░ ░░░░░░░░░░░ ░▒░ ░░░░░░░░░░░░ ░▒▒░ ░░░░░░░░░░░░ ░▒░ ░░░░░░░░░░░░ ░▒▒░ ░░░░░░░░░░░░ ▒▒░ ░░░░░░░░░░░░░ ░▒▒░ ░░░░░░░░░░░░░ ▒▒░ ░░░░░░░░░░░░░ ░▒▒░ ░░░░░░░░░░░░░░ ▒▒░ ░░░░░░░░░░░░░░░░ ░▒▒░ ░░░░░░░░░░░░░ ░▒░ ▒▒░░ ░░░░░░░░░░░░░░░░ ░▒░ ░▒▒░ ░░░░░░░░░░░░░░░░░░░ ░▒░ ░▒░░ ░░░░░░░░░░░░░░░░░░░ ░▒░ ▒▒░░ ░░░░░░░░░░░░░░░░░░ ░░░ ░▒░░░ ░░░░░░░░░░░░░░░░░░░ ░░▒ ░▒░░░ ░░░░░░░░░░░░░░░░░░░ ░░▒░ ▒▒░░░ ░░░░░░░░░░░░░░░░░░░░ ░▒░ ░▒░░░ ░░░░░░░░░░░░░░░░░░░░ ░░▒░ ░▒░░░ ░░░░░░░░░░░░░░░░░░░░░ ░░▒░ ░▒░░░ ░░░░░░░░░░░░░░░░░░░░░░ ░░▒░ ▒▒░░░ ░░░░░░░░░░░░░░░░░░░░░░░ ░░▒▒░ ░▒░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░ ░░▒▒ ░▒░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░▒░ ░▒░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░▒░ ░▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░▒▒░ ▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░▒▒░ ▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░▒▒▒░ ░░░░░ ▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░▒▒▒░░ ░░░░░░░░░░░░░░░ ▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░▒▒▒░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░ ▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░▒▒▒▒▒▒▒▒▒░░░░░░░░░ ░░░░ ▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░ ░░░ ▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░ ░░░ ▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░ ▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░ ▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░ ░▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░ ░▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░ ░▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░ ░▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░ ▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░ ▒▒░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░ ░▒░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░ ░▒░░░░░░░ ░░░░░░░░ ░░░░░ ▒▒░░░░░░ ░░░░ ░▒░░░░░░ ░░░░ ░▒░░░░░░░ ░░░░░░░░░░░ ░░░▒ ▒▒░░░░░░ ░░░░░░░░░░░░░░░░ ░░▒░ ░▒░░░░░░ ░░░░░░░░░░░░░░░░░ ░░▒░ ▒▒░░░░░░ ░░░░░░░░░░░░░░░░░░ ░░▒░ ░▒░░░░░░ ░░░░░░░░░░░░░░░░░░ ░░▒░ ▒▒░░░░░░ ░░░░░░░░░░░░░░░░░░░░ ░░▒░ ░▒░░░░░░ ░░░░░░░░░░░░░░░░░░░░░ ░░▒░ ▒▒░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░ ░░▒░ ░▒░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░ ░░▒░ ░▒░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░ ░░░▒░ ▒▒░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒░ ░▒░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒ ░▒░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░▒░ ░▒░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░▒░ ░▒░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░▒░ ▒▒░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░▒▒ ░▒▒░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░▒░ ░▒▒░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░▒▒░ ░▒▒░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░▒░ ░▒▒░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░▒▒░ ░▒▒░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░▒░ ░▒▒░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░▒▒ ░▒░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░▒▒░ ░▒░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░▒▒░ ░▒▒░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░▒▒▒ ░░▒░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░▒▒▒ ░▒▒░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░▒▒▒ ░░▒░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░▒▒▒ ░▒▒░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░▒▒░ ░▒▒░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░▒▒▒░ ░▒▒▒░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░▒▒▒░ ░░▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒▒░ ░░▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒▒░░ ░░▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒▒░░ ░░░▒▒▒▒▒░░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒░░ ░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░ ░░░░░░░░░░░░░░ XdndAware(ATOM) = BITMAP WM_NAME(STRING) = _NET_WM_NAME(UTF8_STRING) = "Plasma" _MOTIF_WM_HINTS(_MOTIF_WM_HINTS) = 0x3, 0x4, 0x0, 0x0, 0x0 _NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_DOCK _XEMBED_INFO(_XEMBED_INFO) = 0x0, 0x1 WM_CLIENT_LEADER(WINDOW): window id # 0x11e0000a WM_HINTS(WM_HINTS): Client accepts input or input focus: False Initial state is Normal State. _NET_WM_PID(CARDINAL) = 551 WM_CLASS(STRING) = "plasmashell", "plasmashell" WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING WM_NORMAL_HINTS(WM_SIZE_HINTS): user specified location: 1280, 1044 user specified size: 1920 by 36 program specified minimum size: 1920 by 36 program specified maximum size: 1920 by 36 window gravity: Static ```

I confirmed that the value was correctly added to the window by running xprop -id 0xa00011. After that I restarted quicktile in debug mode, but still did not get any output regarding struts.

It occurs to me that, if GNOME Shell isn't setting struts, it's probably also not making proper use of the mechanism QuickTile uses to get a list of top-level windows: The WM putting a list of top-level windows into the _NET_CLIENT_LIST property on the root window.

Now, to be fair, that is a SHOULD and not a MUST, but it works everywhere else.

SimonEggert commented 4 years ago

Is that line all you got?

Unfortunately that's all there is when running xprop on the dock without anything else. When using the provided id in xprop -id 0xa00011 I get

_NET_WM_STRUT_PARTIAL(CARDINAL) = 0, 0, 27, 68, 0, 0, 0, 0, 0, 50, 1023
_NET_WM_USER_TIME(CARDINAL) = 3771079
WM_HINTS(WM_HINTS):
        Client accepts input or input focus: True
        Initial state is Normal State.
XdndProxy(WINDOW): window id # 0xa00011
XdndAware(ATOM) = BITMAP
WM_PROTOCOLS(ATOM): protocols  WM_DELETE_WINDOW, _NET_WM_PING
WM_NORMAL_HINTS(WM_SIZE_HINTS):
        program specified minimum size: 640 by 480
        program specified maximum size: 640 by 480
_NET_WM_NAME(UTF8_STRING) = "gnome-shell"
_NET_WM_PID(CARDINAL) = 2445
WM_LOCALE_NAME(STRING) = "en_US.UTF-8"
WM_CLIENT_MACHINE(STRING) = "simon"

with the first line being the one I added manually. It was missing before that.

Examining the bare desktop with xprop just returns: WM_NAME(STRING) = "mutter guard window"

ssokolow commented 4 years ago

Well, I can't do anything today or tomorrow but, once I've cleared out the more pressing concerns, maybe I'll try spinning up an Ubuntu 20.04 VM to see if I can find a solution better than "allow the user to manually specify the struts".

SimonEggert commented 4 years ago

No hurry, I'll still be here in a few days 😉 Looking forward to your findings!

ssokolow commented 4 years ago

Sorry for the delay. I've got the VM set up and it looks like GNOME might have decided to provide their own non-standard solution.

What does this command say on your system?

xprop -root | grep _GTK_WORKAREAS_

I need to see what it reports on a system not as artificial as my VM, but my intuition is that the following might work, since it appears that, unlike _NET_WORKAREA, _GTK_WORKAREAS provides per-monitor pre-calculated workarea rectangles:

  1. Retrieve the value of _NET_CURRENT_DESKTOP
  2. Use the number from it to generate the name of the appropriate _GTK_WORKAREAS_Dx property (eg. _GTK_WORKAREAS_D1 if on Activity 1)
  3. Split the contents of _GTK_WORKAREAS_Dx into chunks of four values.
  4. Take the Nth chunk where N is the index of the current monitor in the information returned by the X server.
SimonEggert commented 4 years ago

Thank you for the investigation. I've tried some other desktop environments in the meantime and am keeping Budgie for now. The problem does not occur there, so you might as well just close this issue.

But in the interest of anyone running into this issue in the future, I've set up a Raspberry Pi running Ubuntu 20.04 with a 1400x900 resolution. That's as close as I can get to a real setup without wiping my system again. Here is the output I am getting:

_GTK_WORKAREAS_D1(CARDINAL) = 0, 27, 1440, 805
_GTK_WORKAREAS_D0(CARDINAL) = 0, 27, 1440, 805
_NET_SUPPORTED(ATOM) = _NET_WM_NAME, _NET_CLOSE_WINDOW, _NET_WM_STATE, _NET_WM_STATE_SHADED, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_DESKTOP, _NET_NUMBER_OF_DESKTOPS, _NET_CURRENT_DESKTOP, _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DESKTOP, _NET_WM_WINDOW_TYPE_DOCK, _NET_WM_WINDOW_TYPE_TOOLBAR, _NET_WM_WINDOW_TYPE_MENU, _NET_WM_WINDOW_TYPE_UTILITY, _NET_WM_WINDOW_TYPE_SPLASH, _NET_WM_WINDOW_TYPE_DIALOG, _NET_WM_WINDOW_TYPE_DROPDOWN_MENU, _NET_WM_WINDOW_TYPE_POPUP_MENU, _NET_WM_WINDOW_TYPE_TOOLTIP, _NET_WM_WINDOW_TYPE_NOTIFICATION, _NET_WM_WINDOW_TYPE_COMBO, _NET_WM_WINDOW_TYPE_DND, _NET_WM_WINDOW_TYPE_NORMAL, _NET_WM_STATE_MODAL, _NET_CLIENT_LIST, _NET_CLIENT_LIST_STACKING, _NET_WM_STATE_SKIP_TASKBAR, _NET_WM_STATE_SKIP_PAGER, _NET_WM_ICON, _NET_WM_ICON_GEOMETRY, _NET_WM_MOVERESIZE, _NET_ACTIVE_WINDOW, _NET_WM_STRUT, _NET_WM_STATE_HIDDEN, _NET_WM_STATE_FULLSCREEN, _NET_WM_PING, _NET_WM_PID, _NET_WORKAREA, _NET_SHOWING_DESKTOP, _NET_DESKTOP_LAYOUT, _NET_DESKTOP_NAMES, _NET_WM_ALLOWED_ACTIONS, _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_SHADE, _NET_WM_ACTION_STICK, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_CHANGE_DESKTOP, _NET_WM_ACTION_CLOSE, _NET_WM_STATE_ABOVE, _NET_WM_STATE_BELOW, _NET_STARTUP_ID, _NET_WM_STRUT_PARTIAL, _NET_WM_ACTION_FULLSCREEN, _NET_WM_ACTION_MINIMIZE, _NET_FRAME_EXTENTS, _NET_REQUEST_FRAME_EXTENTS, _NET_WM_USER_TIME, _NET_WM_STATE_DEMANDS_ATTENTION, _NET_MOVERESIZE_WINDOW, _NET_DESKTOP_GEOMETRY, _NET_DESKTOP_VIEWPORT, _NET_WM_USER_TIME_WINDOW, _NET_WM_ACTION_ABOVE, _NET_WM_ACTION_BELOW, _NET_WM_STATE_STICKY, _NET_WM_FULLSCREEN_MONITORS, _NET_WM_STATE_FOCUSED, _NET_WM_BYPASS_COMPOSITOR, _NET_WM_OPAQUE_REGION, _NET_WM_FRAME_DRAWN, _NET_WM_FRAME_TIMINGS, _NET_WM_WINDOW_OPACITY, _NET_RESTACK_WINDOW, _GTK_FRAME_EXTENTS, _GTK_SHOW_WINDOW_MENU, _GTK_EDGE_CONSTRAINTS, _GTK_WORKAREAS

Hope this helps!

ssokolow commented 4 years ago

Are you sure it's 1400x900 and not 1440x900?

Assuming I've got my math right, that data looks like it's indicating a 1440x900 monitor with 27px of panel on top and 68px of panel on the bottom.

SimonEggert commented 4 years ago

Of course you're right. Sorry about that!

mennomenno commented 4 years ago

Same issue exists on Ubuntu 18.04 by the way. After manually setting _NET_WM_STRUT_PARTIAL with the space used by the top bar (tray?) and dock, quicktile aligns the windows without overlap.

ssokolow commented 4 years ago

*nod Does it also have `_GTKWORKAREAS` properties?

(I suppose, worst case, I could go with the option where the constraints are specified manually, but have an option which tries to discover un-announced panels by creating a bunch of windows in the cardinal and ordinal positions and seeing where they get shoved to, then saving the results to the config file.)

mennomenno commented 4 years ago

No _GTKWORKAREAS* here. I stole the offsets from _NET_WORKAREA.

ssokolow commented 4 years ago

Ugh. That makes three situations I need to find time to address. (Obeying _GTK_WORKAREAS_* so it Just Works™ as often as possible, addressing IceWM (#118), and having a "discover by attempting to place windows" fallback of some kind.)

mennomenno commented 4 years ago

I don't envy you... If I can help out by providing some more data/stats, let me know. In the meantime very happy with Quicktile making me the master of my new widescreen monitor.

ssokolow commented 4 years ago

*chuckle* If I can clear out some tools I need a Minimum Viable Product on more urgently, you might see some new tools being thrown in soon.

I'm on Kubuntu 16.04 LTS, which has a problem with KWin starting to ignore drag-based window move/resize after 50 days of uptime and I'm stubborn enough about having to get my desktop back the way I want it after a needless reboot that QuickTile is currently my only means of moving and resizing windows.

Gazer commented 4 years ago

Hi, thanks for this great app!. I've been working on a hotfix for this based on the comments of this issue. It is definitely not perfect but works at least for my use case.

ssokolow commented 4 years ago

Sorry for the delayed response.

I'm currently working to migrate my system to some new hard drives (multiple terabytes take time to copy) and do a "clean upgrade" from Kubuntu 16.04 LTS to 20.04 LTS (I let my Ansible deployment scripts atrophy and need to fix them up) but I'll see if I can find time to work on QuickTile in the not too distant future.

Having a starting point to poke at will definitely help things though, to be honest, half the delay was that I don't run GNOME and have been too busy to shuffle files around to make room and then set up a GNOME VM for testing. (Something the new hard drives will help with.)

psalaberria002 commented 2 years ago

Got hit by this issue. Were you able to test it with GNOME? It's been a while since the last message, but trying my lack anyway :)

ssokolow commented 2 years ago

Life sorta fell apart and I'm working on pulling things back together.

No promises, but I'll leave this tab open and try to get to it whenever I can justify interrupting things to diagnose why my "only un-pin the nVidia driver version for updates during restarts" helper failed, end my X session, and reboot to bring the kernel module and libGL versions back into sync and get accelerated graphics back.

Could be a while though. Psychologically, I'd rather go several weeks without the ability to launch anything that requires OpenGL than have to reopen and reposition all the stuff I leave open on my desktop when I go to bed. That's why I have a UPS and, at one point, wrote my own minimal update notifier to kill off the "reboot to update your kernel" nags.

(Yeah, in theory X Session Management Protocol should enable KDE to do that automatically but, in practice, few of the applications I use implement it and those that do tend to implement it brokenly.)

ssokolow commented 1 year ago

GNOME is enough of a pain to virtualize that I've only tested under the 22.04 I installed to reproduce another bug, not the 20.04 mentioned here, but this appears to have been fixed by the new code to use _GTK_WORKAREAS_D0 if present.