You are not logged in.

#1 2019-08-29 11:00:45

karlospv94
Member
Registered: 2016-10-12
Posts: 101

Save and restore the position of the windows in KDE

Hi all!

I need to save and then restore the position of the windows from all the applications running in the system. I.e: firefox, terminals, ...

At some point I use a xrandr command to disable and enable again after few seconds one external monitor I have connected. At this moment, I have each window in a position, but when I disable and re-enable the monitor, all of them end up scattered and I need to move them to the position I want.

My question is, is there any way to save those positions before disabling the monitor in order to restore them later? BTW I'm using KWin, if that helps.

Thanks!

Offline

#2 2019-08-29 12:31:38

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,370
Website

Re: Save and restore the position of the windows in KDE

karlospv94 wrote:

At some point I use a xrandr command to disable and enable again after few seconds

Why?  This sounds like an X-Y problem, there may be a better way of acheiving whatever disabling/enabling is doing (see edit below).

But if there isn't, the following code may help:

#include <stdio.h>
#include <X11/Xlib.h>

Display *dpy;

int save() {
	Window root, ignore, *win_list;
	int i, n, x, y, w, h;
	unsigned int na;
	root = DefaultRootWindow(dpy);
	XQueryTree(dpy, root, &ignore, &ignore, &win_list, &n);
	for (i = 0; i < n; i++) {
		XGetGeometry(dpy, win_list[i], &ignore, &x, &y, &w, &h, &na, &na);
		printf("%X %d %d %u %u\n", win_list[i], x, y, w, h);
	}
	if (n) XFree(win_list);
	return 0;
}

int restore() {
	Window win;
	int x, y;
	unsigned int w, h;
	while (scanf("%X %d %d %u %u\n", &win, &x, &y, &w, &h) == 5)
		XMoveResizeWindow(dpy, win, x, y, w, h);
	return 0;
}

int main(int argc, const char *argv[]) {
	if (!(dpy = XOpenDisplay(0x0)))
		return 1;
	if (argc > 1 && argv[1][0] == 'r')
		return restore();
	return save();
}

Compile, then run and save the output before xrandr, then run again with a "restore" parameter providing the previous output as input, e.g.

program > positions.txt
xrandr --whatever
xrandr --whatever-else
program restore < positions.txt

Note that the code is very basic, it will probably work just as it is, but if KWin has gripes you may want to add checks to the save function to ignore unmapped or extremely small windows.

EDIT:

If this is related to your previous post have you considered rather than disabling the second output, just set it's brightness to zero?  I'm not sure what KDE "activities" are, so I'm not sure if having the additional screen ("muted" with zero brightness) would affect that activity, but it would prevent you from having to save and restore window positions.

Last edited by Trilby (2019-08-29 12:36:28)


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#3 2019-08-29 12:58:29

sevendogs
Member
From: Texas
Registered: 2016-01-24
Posts: 209

Re: Save and restore the position of the windows in KDE

Does KDE have the ability to save window attributes (size, position) itself? Try right clicking on a given window's titlebar to see what is offered. I know fluxbox can do this.


"Give a man a truth and he will think for a day. Teach a man to reason and he will think for a lifetime"

Offline

#4 2019-08-29 13:27:46

seth
Member
Registered: 2012-09-03
Posts: 64,526

Re: Save and restore the position of the windows in KDE

From the other post, the problem is caused by the dynamic output being left of the permanent. If flipping the layout is an option, you can probably sidestep this.
This will also make Trilby's code "fail" in case you try to store on the dual setup and restore on the single one since the window geometries are not aware of the output layout (to the core protocol, there's just one huge output that somehow changes its size, a window start started on 2020,100 now needs to move to 100,100)

Offline

#5 2019-08-31 12:05:30

karlospv94
Member
Registered: 2016-10-12
Posts: 101

Re: Save and restore the position of the windows in KDE

Yes, the point is that I need to disable the second output because I need this for sharing the screen on meetings. So when I share the screen without disabling one of the monitors other people cannot see well my screen (because it captures two outputs).
Disabling one of them I can share only the other one. But yes, are you are pointing out, KDE loses the reference to that monitor so it cannot restore the windows position later after activating it again

Offline

#6 2019-08-31 12:29:06

seth
Member
Registered: 2012-09-03
Posts: 64,526

Re: Save and restore the position of the windows in KDE

Then Trilby's code should work and there's actually a scripting interface to kwin that you can (probably) utilize for a similar effect (and maybe even bind to the resolution change)

Offline

#7 2019-09-02 10:12:10

karlospv94
Member
Registered: 2016-10-12
Posts: 101

Re: Save and restore the position of the windows in KDE

This week I won't have the computer but I will take a look at it and will leave a comment over here. Thanks!

Offline

#8 2019-09-09 15:54:20

karlospv94
Member
Registered: 2016-10-12
Posts: 101

Re: Save and restore the position of the windows in KDE

Trilby wrote:
karlospv94 wrote:

At some point I use a xrandr command to disable and enable again after few seconds

Why?  This sounds like an X-Y problem, there may be a better way of acheiving whatever disabling/enabling is doing (see edit below).

But if there isn't, the following code may help:

#include <stdio.h>
#include <X11/Xlib.h>

Display *dpy;

int save() {
	Window root, ignore, *win_list;
	int i, n, x, y, w, h;
	unsigned int na;
	root = DefaultRootWindow(dpy);
	XQueryTree(dpy, root, &ignore, &ignore, &win_list, &n);
	for (i = 0; i < n; i++) {
		XGetGeometry(dpy, win_list[i], &ignore, &x, &y, &w, &h, &na, &na);
		printf("%X %d %d %u %u\n", win_list[i], x, y, w, h);
	}
	if (n) XFree(win_list);
	return 0;
}

int restore() {
	Window win;
	int x, y;
	unsigned int w, h;
	while (scanf("%X %d %d %u %u\n", &win, &x, &y, &w, &h) == 5)
		XMoveResizeWindow(dpy, win, x, y, w, h);
	return 0;
}

int main(int argc, const char *argv[]) {
	if (!(dpy = XOpenDisplay(0x0)))
		return 1;
	if (argc > 1 && argv[1][0] == 'r')
		return restore();
	return save();
}

Compile, then run and save the output before xrandr, then run again with a "restore" parameter providing the previous output as input, e.g.

program > positions.txt
xrandr --whatever
xrandr --whatever-else
program restore < positions.txt

Note that the code is very basic, it will probably work just as it is, but if KWin has gripes you may want to add checks to the save function to ignore unmapped or extremely small windows.

EDIT:

If this is related to your previous post have you considered rather than disabling the second output, just set it's brightness to zero?  I'm not sure what KDE "activities" are, so I'm not sure if having the additional screen ("muted" with zero brightness) would affect that activity, but it would prevent you from having to save and restore window positions.

Actually the execution of the restore is not taking effect. I have one terminal and one firefox opened and I have the following output when executing it:

carlos@turing ~/Desarrollo/activity-manager
➜ ./program > positions.txt                                                                                                                                                                                                                                                              
carlos@turing ~/Desarrollo/activity-manager
➜ cat positions.txt                                                                                                                                                                                                                                                                      
2200041 1920 0 2560 1440
2200047 0 0 1920 1080
22006E0 3322 0 1158 1004
220085A 1920 0 2560 1410
220006A 1920 1410 2560 30
2200057 0 54 1 972
2200056 0 0 54 54
2200055 0 0 1 1
2200007 0 0 1 1
400004 0 0 3 3
800004 0 0 3 3
C00004 0 0 3 3
C00005 0 0 1 1
E00004 0 0 3 3
1200004 0 0 3 3
1200006 0 0 1 1
1600004 0 0 3 3
1800004 0 0 3 3
1A00004 0 0 3 3
1C00004 0 0 3 3
1400004 0 0 3 3
A00004 0 0 3 3
2000004 0 0 3 3
1800005 0 0 1 1
1800006 0 0 1 1
2200004 0 0 3 3
2400004 0 0 3 3
2600004 0 0 3 3
2200005 0 0 1 1
2800004 0 0 3 3
2800005 0 0 1 1
2400005 0 0 1 1
2C00004 0 0 3 3
2400007 0 0 640 480
2400009 0 0 1 1
A00011 0 0 1 1
3000004 0 0 3 3
A00012 0 0 1 1
2E00001 10 10 10 10
2200006 -1 -1 1 1
2200008 0 0 160 160
220000A 0 0 1 1
220000B 0 0 160 160
3000005 0 0 1 1
3400004 0 0 3 3
220000E 0 0 1 1
3A00001 10 10 10 10
3C00004 0 0 3 3
3600004 0 0 3 3
3E00004 0 0 3 3
4000004 0 0 3 3
4200004 0 0 3 3
4400004 0 0 3 3
4600004 0 0 3 3
4800004 0 0 3 3
4A00004 0 0 3 3
4C00004 0 0 3 3
4E00004 0 0 3 3
5200004 0 0 3 3
5000004 0 0 3 3
5400004 0 0 3 3
5600004 0 0 3 3
5800004 0 0 3 3
5A00004 0 0 3 3
5C00004 0 0 3 3
5E00004 0 0 3 3
6000004 0 0 3 3
3A0000C -1 -1 1 1
200002 0 0 1 1
800005 0 0 1 1
220003A 0 0 1 1
220003B 0 0 1 1
2000011 0 0 1 1
2000013 1920 0 12 1410
2000015 0 0 1 1
200001A 0 0 12 1080
2200045 0 0 795 503
200004B 0 0 160 160
200004E 1920 786 480 624
2000051 0 0 12 12
200007C 0 0 640 480
A00013 0 0 3 3
2000087 0 0 3 3
6400004 0 0 3 3
6600001 10 10 10 10
6600003 0 0 200 200
6E00001 0 0 1 1
6A0000A 0 0 1 1
6800005 0 0 1 1
6800006 -100 -100 10 10
22005DB 0 0 160 160
7400001 10 10 10 10
7400011 -100 -100 10 10
7200001 10 10 10 10
7400014 -100 -100 10 10
7400017 0 0 100 100
7600001 10 10 10 10
7800001 10 10 10 10
7A00001 10 10 10 10
7C00001 10 10 10 10
7E00001 10 10 10 10
8000001 10 10 10 10
8600004 0 0 3 3
8600005 0 0 1 1
8600009 0 0 1 1
7400036 0 0 200 200
8800004 0 0 3 3
8C00001 10 10 10 10
8C00003 0 0 100 100
8C0001C -100 -100 10 10
8C0001F 0 0 200 200
8C00028 0 0 200 200
8C0002D 0 0 200 200
8C00031 0 0 200 200
8C00039 0 0 200 200
8C000A3 0 0 200 200
8C000B7 0 0 200 200
8C000BB 0 0 200 200
7400065 0 0 200 200
8400001 10 10 10 10
8A00004 0 0 3 3
8E00001 10 10 10 10
8A00008 0 0 1 1
7400083 3935 116 148 31
2000079 4004 1020 444 390
8A00029 0 0 3 3
A0000F 2935 0 530 41
200014C 4163 1242 132 170
2000054 2560 888 1920 522
9000001 10 10 10 10
8600067 0 0 3 3
74000FC 2207 90 405 231
8C00010 1920 0 1024 701
74000B5 3050 538 300 160
680001B 3575 812 52 27
8A0000A 1920 0 2560 1440
7400108 2804 498 265 109
2000099 2645 1246 219 164
8A00006 2808 384 800 600
120000D 0 0 1 1
7400042 3562 61 463 31
7400058 2722 233 213 31
6800001 2662 290 1024 768
740003E 1920 102 2560 393

So I move the firefox to the external monitor and I execute the following command:

carlos@turing ~/Desarrollo/activity-manager
➜ ./program restore < positions.txt

I would expect the firefox to be restored to its original position (from the external monitor to the laptop's screen) but anything happens...

Offline

#9 2023-02-26 23:56:52

grandrew
Member
Registered: 2022-12-20
Posts: 6

Re: Save and restore the position of the windows in KDE

Here is the new script that works in 2023:

usage

./restore.sh save
./restore.sh restore

script:

#/bin/bash
MODE=$1
if [ -e $MODE ]; then
echo "$0 save - to save"
echo "$0 restore - to restore"
exit
fi
if [ $MODE = "save" ]; then
        echo "saving"
        xwininfo -tree -root > /tmp/savewin.log
fi
if [ $MODE = "restore" ]; then
        echo "restoring"
        while read p; do
          LN=`echo $p | xargs`
          WINID=$(echo $LN | cut -d' ' -f1)
          XYWH=$(echo $LN | rev | cut -d' ' -f2 | rev)
          W=$(echo $LN | rev | cut -d' ' -f2 | rev | cut -d'x' -f1)
          H=$(echo $LN | rev | cut -d' ' -f2 | rev | cut -d'x' -f2 | cut -d'+' -f1)
          X=$(echo $LN | rev | cut -d' ' -f1 | rev | cut -d'x' -f2 | cut -d'+' -f2)
          Y=$(echo $LN | rev | cut -d' ' -f1 | rev | cut -d'x' -f2 | cut -d'+' -f3)
          if [ $H -lt 300 ]; then 
                  continue; 
          fi
          wmctrl -i -r $((${WINID})) -e 1,$(($X-2)),$(($Y-25)),$W,$H
        done <<< $(cat /tmp/savewin.log | grep " +" | grep "0x" | grep -v " +0" | grep -v "+-")
fi

Offline

#10 2023-02-27 00:04:45

2ManyDogs
Forum Fellow
Registered: 2012-01-15
Posts: 4,646

Re: Save and restore the position of the windows in KDE

Closing this old thread.

Offline

Board footer

Powered by FluxBB