Open crashvb opened 2 years ago
Update: found a typo in what I was trying where I was using _NET_FRAME_EXTENDS
instead of _NET_FRAME_EXTENTS
; after testing with the new value, nothing has changed.
I've only ever used xprop for querying windows, not setting anything. Have you tried wmctrl
for this? I think it's a bit more commonly used for this sort of application.
@mtwebster Thank you for the reply.
Yes, I have tried using wmctrl; however, I don't know how to assign the value of _NET_WM_WINDOW_TILE_INFO
using that tool.
Update:
I found out that I was using the wrong format for the cardinal properties.
Updated /tmp/xprop.formats:
_NET_FRAME_EXTENTS 0c
_NET_WM_STATE 32a
_NET_WM_WINDOW_TILE_INFO 0c
... now results in this error:
$ xprop -id 142606346 -fs /tmp/xprop.formats -set _NET_WM_WINDOW_TILE_INFO 4,1,0,720,2560,720,0,0
X Error of failed request: BadValue (integer parameter out of range for operation)
Major opcode of failed request: 18 (X_ChangeProperty)
Value in failed request: 0x0
Serial number of failed request: 15
Current serial number in output stream: 17
... but I am unsure how to find what are the limits of the range, or even which value (there are multiple '0's provided) is out of range ...
I believe that I have located the relevant code within core/window.c::set_net_wm_state that assigns values to both _NET_WM_STATE
and _NET_WM_WINDOW_TILE_INFO
, and I don't see any special range checking; which leads me to believe that this is being done by something at a lower level (x11?) and not the WM.
I did check ~/.xsession.errors, but I don't see any entries related to this action.
Update:
I have learned way more information about window managers than I was expecting to need to know; however, a answer to this question still eludes me.
To progress, I have wrapped python-xlib and implemented about 90% of EWMH, but the _NET_WM_STATE_TILED
does not appear to be part of that standard. More so, it would appear that is it precluded from existing with a _NET
prefix; however, I am not familiar with the history of things in this area.
I have tried various combinations of actions including:
_NET_WM_STATE
to include _NET_WM_STATE_TILED
and _NET_WM_STATE_MAXIMIZED_VERT
, assign _NET_WM_TILE_INFO
, assign _NET_FRAME_EXTENDS
._NET_WM_STATE_TILED
to _NET_WM_STATE
, assign _NET_FRAME_EXTENDS
._NET_MOVERESIZE_WINDOW
, then variations on _NET_WM_STATE
, both w/ and w/o _NET_FRAME_EXTENDS
._NET_WM_STATE
, assign _NET_FRAME_EXTENDS
, map the window.I'm still trying to wrap my head around what I have observed, but this is my understanding at this point:
_NET_MOVERESIZE_WINDOW
; however, it does not behave correctly when using the sup+(arrows) keybindings -- which is expected, because it's not actually tiled. Also the original geometry is lost at this point from the WM._NET_WM_STATE_MAXIMIZED_VERT
state, but ignores the assignment of _NET_WM_STATE_TILED
; regardless if I attempt to assign _NET_WM_TILE_INFO
prior to the state assignment, after, or not at all._NET_FRAME_EXTENDS
; I don't believe that it's failing silently, nor do I see anything in .xsession-errors
, but I have not ruled it out.Side Notes:
Update:
I (think) I have successfully assigned the properties to the window; however, no action is taken by the WM to perform the tiling.
I have used python-xlib window.changeproperty() method to assign the frame extents (just noticed the typo, again, the the post above =/ ... extenTs)_ and tile info (i.e. XChangeProperty), followed by window.send_event() to assign the WM state via a message to the root window. ... then ... nothing happens (xprop verification below).
When I attempt to assign _NET_WM_STATE using change_property(), instead of notifying the root window as the docs say, nothing happens, as expected. When I attempt to assign _NET_WM_STATE_MAXIMIZED_VERT
as the second state in the client message, only that state is assigned, _NET_WM_STATE_TILED
is ignored, and _NET_WM_WINDOW_TILE_INFO
is removed by the WM?!?
I was looking into the codebase of cinnamon, and noticed that it uses GTK to emit a signal, and both the muffin code overview and inline comments mention that GTK events are processed by display.c::event_callback(), but I'm not familiar enough (yet?) to trace how / where the signal is processed. -- My current understanding is that GTK assigns values to a "meta" object that is then referenced in response to signaling/events/messages??? (i.e. window->tile_mode window->tile_type) ...
I did come across PyGObject; however, I'm not sure that going that route is needed if it's only wrapping lower-level signalling, or effectively assigning the same state (i.e. That either way it's muffin making the change).
Additionally, I was looking for unit-tests of this functionality, or a standard that governs _NET_WM_WINDOW_TILE_INFO
, but I might have been looking in the wrong places ...
What I assigned:
_NET_WM_WINDOW_TILE_INFO(CARDINAL) = 4, 1, 0, 720, 2560, 720, 0, 0
XKLAVIER_STATE(INTEGER) = 0, -269574400
_GTK_EDGE_CONSTRAINTS(CARDINAL) = 170
_NET_WM_STATE(ATOM) = _NET_WM_STATE_TILED
WM_STATE(WM_STATE):
window state: Normal
icon window: 0x0
_NET_FRAME_EXTENTS(CARDINAL) = 0, 1, 24, 1
_NET_WM_DESKTOP(CARDINAL) = 0
_NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_FULLSCREEN, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_SHADE, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_CHANGE_DESKTOP, _NET_WM_ACTION_CLOSE, _NET_WM_ACTION_ABOVE, _NET_WM_ACTION_BELOW
_NET_WM_PID(CARDINAL) = 3743926
WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW
SM_CLIENT_ID(STRING) = "1066fafc84f83a982816456722452259900000021571259"
WM_CLIENT_LEADER(WINDOW): window id # 0x860000a
WM_LOCALE_NAME(STRING) = "en_US.UTF-8"
WM_CLASS(STRING) = "xclock", "XClock"
WM_HINTS(WM_HINTS):
Client accepts input or input focus: False
Initial state is Normal State.
bitmap id # to use for icon: 0x8600001
bitmap id # of mask for icon: 0x8600003
WM_NORMAL_HINTS(WM_SIZE_HINTS):
program specified size: 164 by 164
window gravity: NorthWest
WM_CLIENT_MACHINE(STRING) = "s27lxlap"
WM_COMMAND(STRING) = { "xclock" }
WM_ICON_NAME(STRING) = "xclock"
WM_NAME(STRING) = "xclock"
What was assigned manually:
_NET_WM_WINDOW_TILE_INFO(CARDINAL) = 4, 1, 0, 707, 2560, 707, 0, 0
XKLAVIER_STATE(INTEGER) = 0, -269574400
_GTK_EDGE_CONSTRAINTS(CARDINAL) = 170
_NET_WM_STATE(ATOM) = _NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_TILED
WM_STATE(WM_STATE):
window state: Normal
icon window: 0x0
_NET_FRAME_EXTENTS(CARDINAL) = 0, 1, 24, 1
_NET_WM_DESKTOP(CARDINAL) = 0
_NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_FULLSCREEN, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_SHADE, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_CHANGE_DESKTOP, _NET_WM_ACTION_CLOSE, _NET_WM_ACTION_ABOVE, _NET_WM_ACTION_BELOW
_NET_WM_PID(CARDINAL) = 3747321
WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW
SM_CLIENT_ID(STRING) = "1066fafc84f83a9828164567226354832400000021571260"
WM_CLIENT_LEADER(WINDOW): window id # 0x840000a
WM_LOCALE_NAME(STRING) = "en_US.UTF-8"
WM_CLASS(STRING) = "xclock", "XClock"
WM_HINTS(WM_HINTS):
Client accepts input or input focus: False
Initial state is Normal State.
bitmap id # to use for icon: 0x8400001
bitmap id # of mask for icon: 0x8400003
WM_NORMAL_HINTS(WM_SIZE_HINTS):
program specified size: 164 by 164
window gravity: NorthWest
WM_CLIENT_MACHINE(STRING) = "s27lxlap"
WM_COMMAND(STRING) = { "xclock" }
WM_ICON_NAME(STRING) = "xclock"
WM_NAME(STRING) = "xclock"
Aside from the variance between 707
and 720
, which I suspect is due to not using _NET_REQUEST_FRAME_EXTENTS
, they appear to be equivalent. Is there something I'm missing?
Found this in src/core/window-props.c:
846 static void
847 reload_net_wm_state (MetaWindow *window,
848 MetaPropValue *value,
849 gboolean initial)
850 {
851 int i;
852
853 /* We know this is only an initial window creation,
854 * clients don't change the property.
855 */
856
857 if (!initial) {
858 /* no, they DON'T change the property */
859 meta_verbose ("Ignoring _NET_WM_STATE: we should be the one who set "
860 "the property in the first place\n");
861 return;
862 }
... doesn't look good, but not sure of the impact yet ...
Update:
I've continued down the python-xlib path. I implemented a few workarounds including using moveresize
and feeding keys into the WM to get windows to tile. I've been using them for about a year, but they are messy and still feel like a hack.
Recently, I've even asked ChatGPT to help (despite the 2021 cutoff), but it didn't yield anything new...
Me: Please provide example python code to assign the "NET_WM_WINDOW_TILE_INFO" atom using the Xlib library targeted at the Muffin window manager.
ChatGPT: Sure! Here's an example Python code snippet that demonstrates how to assign the "NET_WM_WINDOW_TILE_INFO" atom using the Xlib library, specifically targeting the Muffin window manager:
from Xlib import X, display, protocol, Xatom
d = display.Display()
root = d.screen().root
win = root.create_window(0, 0, 500, 500, 0, d.screen().root_depth)
win.change_property(d.get_atom("_NET_WM_WINDOW_TYPE"), Xatom.WINDOW, 32, [d.get_atom("_NET_WM_WINDOW_TYPE_NORMAL")])
info = [ 1, # flags (1 = tileable) 0, # left inset 0, # right inset 0, # top inset 0, # bottom inset 0, # start of content area (x-coordinate) 0, # start of content area (y-coordinate) 500, # width of content area 500 # height of content area ] win.change_property(d.get_atom("_NET_WM_WINDOW_TILE_INFO"), d.get_atom("32_CARDINAL"), 32, info)
win.map() d.flush()
> **Me**: I'm sorry, but this does not work. Are you sure the Muffin window manager supports assigning the "NET_WM_WINDOW_TILE_INFO" property?
>
> **ChatGPT**: I apologize for the confusion. You are correct that Muffin does not currently support the _NET_WM_WINDOW_TILE_INFO property.
>
> In fact, this property is not part of the EWMH specification, but rather an experimental extension that was proposed by the Openbox window manager. While some tiling window managers have implemented this extension, it is not widely supported and is not part of the standard EWMH specification.
>
> If you are looking to implement tiling behavior in Muffin, you may want to explore other options such as using a tiling extension like shellshape, or implementing your own tiling logic within your application.
>
> Once again, I apologize for any confusion caused by my earlier response.
I'm currently using Cinnamon on Linux Mint, so I'm pretty sure I'm sticking with Muffin; but at least I got some feedback that somewhere on the internet, other people have tried something similar. ;)
Did you check all the tiling functions directly available via keyboard shortcuts (see in the keyboard settings), some of them aren't assigned to keys in default settings.
Am 9. April 2023 04:53:37 MESZ schrieb Richard Davis @.***>:
Update:
I've continued down the python-xlib path. I implemented a few workarounds including using
moveresize
and feeding keys into the WM to get windows to tile. I've been using them for about a year, but they are messy and still feel like a hack.Recently, I've even asked ChatGPT to help (despite the 2021 cutoff), but it didn't yield anything new...
Me: Please provide example python code to assign the "NET_WM_WINDOW_TILE_INFO" atom using the Xlib library targeted at the Muffin window manager.
ChatGPT: Sure! Here's an example Python code snippet that demonstrates how to assign the "NET_WM_WINDOW_TILE_INFO" atom using the Xlib library, specifically targeting the Muffin window manager:
from Xlib import X, display, protocol, Xatom
Create a connection to the X server
d = display.Display()
Get the root window
root = d.screen().root
Create a window and set its properties
win = root.create_window(0, 0, 500, 500, 0, d.screen().root_depth)
Set the "NET_WM_WINDOW_TYPE" property to "NORMAL"
win.change_property(d.get_atom("_NET_WM_WINDOW_TYPE"), Xatom.WINDOW, 32, [d.get_atom("_NET_WM_WINDOW_TYPE_NORMAL")])
Set the "NET_WM_WINDOW_TILE_INFO" property to indicate how the window should be tiled
info = [ 1, # flags (1 = tileable) 0, # left inset 0, # right inset 0, # top inset 0, # bottom inset 0, # start of content area (x-coordinate) 0, # start of content area (y-coordinate) 500, # width of content area 500 # height of content area ] win.change_property(d.get_atom("_NET_WM_WINDOW_TILE_INFO"), d.get_atom("32_CARDINAL"), 32, info)
Map the window and flush changes to the server
win.map() d.flush()
> **Me**: I'm sorry, but this does not work. Are you sure the Muffin window manager supports assigning the "NET_WM_WINDOW_TILE_INFO" property? > > **ChatGPT**: I apologize for the confusion. You are correct that Muffin does not currently support the _NET_WM_WINDOW_TILE_INFO property. > > In fact, this property is not part of the EWMH specification, but rather an experimental extension that was proposed by the Openbox window manager. While some tiling window managers have implemented this extension, it is not widely supported and is not part of the standard EWMH specification. > > If you are looking to implement tiling behavior in Muffin, you may want to explore other options such as using a tiling extension like shellshape, or implementing your own tiling logic within your application. > > Once again, I apologize for any confusion caused by my earlier response. I'm currently using Cinnamon on Linux Mint, so I'm pretty sure I'm sticking with Muffin; but at least I got some feedback that somewhere on the internet, other people have tried something similar. ;) -- Reply to this email directly or view it on GitHub: https://github.com/linuxmint/muffin/issues/612#issuecomment-1501025838 You are receiving this because you are subscribed to this thread. Message ID: ***@***.***>
@DirkHaar thank you for the reply :)
Yes, I do have something working, but there are edge cases where things go sideways. (e.g. If call to activate / focus the window is not successful prior sending the keys then the wrong window, or no window, ends up being tiled)
My hope is to be able to programatically assign the desired state in such a way that it is both deterministic and compatible with what the underlying WM is doing. (i.e. If I snap a window, that the WM also considers the window to be snapped).
To keep the WM informed about the status you pretty sure must use its function calls for tiling (just saying, in case you are manipulating size/width/height manually). But I guess that's more a question going to the muffin developers.
Agreed; based on what I know now, I'm going to convert this question into a bug.
IssueQuestionI'm trying to tile xclock using xprop but it doesn't appear to be working. The window does not resize or change location after executing the command even though the properties appear to be updated. Is this a bug, or am I attempting to do something that is not supported / is out of alignment with how a window manager is intended to operate?
Steps to reproduce
Command execution (resolution: 5120x1415):
Full xprop after command execution:
contents of /tmp/xprop.formats:
Expected behaviour
The changes are detected and the window is tiled to the bottom left corner (LLC).
Other information
I did come across an issue with xprop being unable to assign multiple atom values, and have opened a related question to the xprop developers. But I am not sure if that is the underlying issue, as I have also tested with each
_NET_WM_STATE
atom value individually with the same results. From what I can tell by browsing this repository,_NET_WM_STATE_MAXIMIZED_VERT
was added to accommodate some GTK behavior; however, it's my understanding that xclock does not use GTK.