Bug 469834 - cannot change both width and height of client geometry (maybe a race?)
Summary: cannot change both width and height of client geometry (maybe a race?)
Status: CONFIRMED
Alias: None
Product: kwin
Classification: Plasma
Component: scripting (other bugs)
Version First Reported In: 5.25.2
Platform: Debian testing Linux
: NOR normal
Target Milestone: ---
Assignee: KWin default assignee
URL:
Keywords: wayland-only
Depends on:
Blocks:
 
Reported: 2023-05-16 04:16 UTC by Antonio Russo
Modified: 2026-02-14 06:02 UTC (History)
3 users (show)

See Also:
Latest Commit:
Version Fixed/Implemented In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Antonio Russo 2023-05-16 04:16:45 UTC
STEPS TO REPRODUCE
1. startplasma-interactiveconsole --kwin
2. Run this script:
```
const clients = workspace.clientList();
var client = clients[clients.length-1];
client.geometry.height = 1000;
client.geometry.width = 1000;
```

(Obviously, make sure that the scripting console is the most recently opened window, otherwise you'll be resizing some other window on your desktop).

OBSERVED RESULT
Only the width is changed. (invert the order to get the height to be changed)

EXPECTED RESULT
Both the height and width are changed.


SOFTWARE/OS VERSIONS
Linux/KDE Plasma: Debian testing
KDE Plasma Version: 4:5.27.2-1
KDE Frameworks Version: 5.103.0-1
Qt Version: 5.15.8-2
Comment 1 Antonio Russo 2023-05-16 04:19:41 UTC
I forgot to mention: this is a wayland regression. It is broken on kwin_wayland, but works on kwin_X11.
Comment 2 David Edmundson 2023-06-13 22:05:15 UTC
To explain what's happening:

client.geometry.height = 1000;
is asking the client for the geometry of (currentWidth, 1000);

client.geometry.width = 1000;
is asking the client for the geometry of (1000, currentHeight);


Changing geometry is an async operation, at the time of the second call, the currentHeight is the frames current height, which is not 1000.

I would say the script code is wrong, set client.geometry to a rect directly. 

Please reopen if there's a reason why your script can't do that.
Comment 3 Antonio Russo 2023-06-13 23:16:36 UTC
Yes, I suspected that the async operations were doing this, but I was never able to figure out how to overcome that.  In particular, I don't know how to instantiate a QRect object (is it spelled "rect"?)?

Could you please give me the exact script that you are saying will allow me to change both the width and height at the same time?  If such a script indeed exists, I definitely agree this bug should be closed.

Thank you,
Antonio
Comment 4 andy 2024-03-08 22:02:32 UTC
(In reply to Antonio Russo from comment #3)
> Yes, I suspected that the async operations were doing this, but I was never
> able to figure out how to overcome that.  In particular, I don't know how to
> instantiate a QRect object (is it spelled "rect"?)?
> 
> Could you please give me the exact script that you are saying will allow me
> to change both the width and height at the same time?  If such a script
> indeed exists, I definitely agree this bug should be closed.
> 
> Thank you,
> Antonio

I figured it out (for plasma 6). You can set the entire frameGeometry object at once. 

var x = 2000
var y = 2000
var width = 200
var height = 200
var left = x
var right = x + width
var top = y
var bottom = y + height
workspace.activeWindow.frameGeometry = {"x":x,"y":y,"width":width,"height":height,"left":left,"right":right,"top":top,"bottom":bottom}

If I query the geometry again (this is in the shell scripting console) I get
{"x":2000,"y":2000,"width":200,"height":339,"left":2000,"right":2200,"top":2000,"bottom":2339}

I was wondering if we have to specify all that or just x,y,width,height. If I don't specify left/right/top/bottom
 workspace.activeWindow.frameGeometry = {"x":x,"y":y,"width":width,"height":height}

if I query the result I get slightly different positioning, but same width and height
 {"x":2000,"y":1861,"width":200,"height":339,"left":2000,"right":2200,"top":1861,"bottom":2200}

But for just a move this works
workspace.activeWindow.frameGeometry = {"x":x,"y":y}


For just a resize lol this doesn't work, it moves the window to (0,0) which is off-screen for my monitor setup.
workspace.activeWindow.frameGeometry = {"width":width,"height":height}
Comment 5 TraceyC 2026-01-30 12:46:55 UTC
I wanted to follow up on this. Antonio, would the suggestion in comment 3 work for you?
Comment 6 Bug Janitor Service 2026-02-14 03:51:27 UTC
๐Ÿ›๐Ÿงน โš ๏ธ This bug has been in NEEDSINFO status with no change for at least 15 days. Please provide the requested information, then set the bug status to REPORTED. If there is no change for at least 30 days, it will be automatically closed as RESOLVED WORKSFORME.

For more information about our bug triaging procedures, please read https://community.kde.org/Guidelines_and_HOWTOs/Bug_triaging.

Thank you for helping us make KDE software even better for everyone!
Comment 7 Antonio Russo 2026-02-14 06:02:32 UTC
Thanks for the hint, andy! Things seem to be a little bit wonky. The following works:

var oldgeometry = workspace.activeWindow.frameGeometry;
workspace.activeWindow.frameGeometry = {"x":oldgeometry["x"],"y":oldgeometry["y"],"width":oldgeometry["width"],"height":oldgeometry["height"]};

(i.e., modify any of these parameters, and you can get the effect you're looking for).  As far as I can tell, top and bottom don't seem to be necessary/useful.  However, you might think that you could do

var oldgeometry = workspace.activeWindow.frameGeometry;
oldgeometry["width"] = 400;
workspace.activeWindow.frameGeometry = oldgeometry;

but that does not work! You have to create a whole new geometry:

var oldgeometry = workspace.activeWindow.frameGeometry;
var newgeometry = {"x":oldgeometry["x"],"y":oldgeometry["y"],"width":oldgeometry["width"],"height":oldgeometry["height"]};
newgeometry["width"] = 400;
workspace.activeWindow.frameGeometry = oldgeometry;

I'm guessing the structure that actually comes out of workspace.activeWindow.frameGeometry is more complicated than a dictionary, then?

I suggest that this is a documentation bug.  I have not read all of the (improved, since 2023!) documentation, but I don't immediately see a statement anywhere explaining any of these quirks.  Moreover, I don't see a description of how a QRect is represented in the scripting API.  (This was part of my original question, and I still don't quite understand it).  Of course, one could dig into the code to figure out how that mapping is done, but it would be nice if the documentation had this information.

Feel free to close this bug, but I do think that the tutorial should include a subset/restatement of this bug report in it, at a minimum.