You are not logged in.

#1 2016-10-07 16:49:47

Observer
Member
Registered: 2016-03-01
Posts: 16

Save the window positions and move windows via shell script

Hi guys,

my desktop pc uses two displays but sometime I must disable the second screen for another system. For this I created a little shell script with xrandr which remove and add the screen "automatically".

The problem is that after the "reconnect" of the second display all windows which was on this display (before the disconnect) are not moved to this second again.

So I think a must write a own solution for this case. I found xlsclients und xwininfo but it seems so that this tools does not work quiet well for me.

xlsclients found many windows but xwininfo delivers wrong values. The position and/or dimensions does not look write. Special: They are the same for all windows.

xwininfo: Window id: 0x3800001 "Sublime Text"

  Absolute upper-left X:  10
  Absolute upper-left Y:  10
  Relative upper-left X:  10
  Relative upper-left Y:  10
  Width: 10
  Height: 10
  Depth: 24
  Visual: 0x21
  Visual Class: TrueColor
  Border width: 0
  Class: InputOutput
  Colormap: 0x20 (installed)
  Bit Gravity State: NorthWestGravity
  Window Gravity State: NorthWestGravity
  Backing Store State: NotUseful
  Save Under State: no
  Map State: IsUnMapped
  Override Redirect State: no
  Corners:  +10+10  -3820+10  -3820-1060  +10-1060
  -geometry 10x10+10+10

If i use xdotool getactivewindo I get another id for the same window and with this id xwininfo delivers better values.

  Absolute upper-left X:  250
  Absolute upper-left Y:  143
  Relative upper-left X:  250
  Relative upper-left Y:  143
  Width: 1344
  Height: 854
[...]
  Corners:  +250+143  -326+143  -326-83  +250-83
  -geometry 1344x854+250-83

So I think that xlsclients detect windows on another "higher" level, which it makes useless for me.

Does anyone know another way to determine all the windows of a display?

PS: Sorry for this kind of english wink

Offline

#2 2016-10-07 16:54:46

Alad
Wiki Admin/IRC Op
From: Bagelstan
Registered: 2014-05-04
Posts: 2,421
Website

Re: Save the window positions and move windows via shell script


Mods are just community members who have the occasionally necessary option to move threads around and edit posts. -- Trilby

Offline

#3 2016-10-07 17:27:48

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

Re: Save the window positions and move windows via shell script

Doing this in bash would be tricky.  But a few lines of C will get it done:

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

typedef struct { Window win; int x, y; unsigned int w, h; } Pos;

int main(int argc, const char **argv) {
	if (argc != 2) return 1;
	Display *dpy = XOpenDisplay(0x0);
	if (!dpy) return 2;
	Window root = DefaultRootWindow(dpy);
	Window wig, *wins;
	int i, n;
	unsigned int ig;
	XQueryTree(dpy, root, &wig, &wig, &wins, &n);
	Pos *p = malloc(n * sizeof(Pos));
	for (i = 0; i < n; ++i)
		XGetGeometry(dpy, (p[i].win = wins[i]), &wig, &p[i].x, &p[i].y, &p[i].w, &p[i].h, &ig, &ig);
	system(argv[1]);
	for (i = 0; i < n; ++i)
		XMoveResizeWindow(dpy, p[i].win, p[i].x, p[i].y, p[i].w, p[i].h);
	free(p)
	return 0;
}

Compile this with `gcc -o someName thisAboveFile.c -lX11` then run it by passing your xrandr command as the first argument, eg

./someName "xrandr --output LVDS1 --auto --output VGA1 --above LVDS1"

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

Offline

#4 2016-10-07 20:14:46

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 78,611

Re: Save the window positions and move windows via shell script

"wmctrl -l"
For a totally different approach: did you try to SIGSTOP/SIGCONT the  WM around the "reconnect"?

Offline

#5 2016-10-08 14:51:36

Observer
Member
Registered: 2016-03-01
Posts: 16

Re: Save the window positions and move windows via shell script

Thank you for your tips! wmctrl looks very good.

Today i build a little test script which works pretty well. My current problem are snapped windows, which are not movable. It seems so that this is not possible (currently).

If someone is interested, this is my test script in this moment (not cleaned up)

#!/bin/bash

if [[ $EUID -ne 0 ]]
then
	echo "This script must be run as root"
	exit 1
fi

declare -A STORAGE

IFS=$'\n'       # make newlines the only separator
set -f          # disable globbing

for line in `wmctrl -G -l`
do
	if [[ $line =~ ^(0x[[:alnum:]]*)[[:space:]]+(0)[[:space:]]+(-?[0-9]*)[[:space:]]+(-?[0-9]*)[[:space:]]+([0-9]*)[[:space:]]+([0-9]*) ]]; then

		if [ ${BASH_REMATCH[3]} -le 1920 ]; then
			STORAGE[${BASH_REMATCH[1]}]="$line";
		fi;
	fi;
done;

xrandr --output DP-1 --off

sleep 5;

xrandr --output DP-1 --mode "1920x1080" --rate 120 --left-of HDMI-0 --primary

sleep 5;

for line in "${STORAGE[@]}"
do
	[[ $line =~ ^(0x[[:alnum:]]*)[[:space:]]+(0)[[:space:]]+(-?[0-9]*)[[:space:]]+(-?[0-9]*)[[:space:]]+([0-9]*)[[:space:]]+([0-9]*) ]];

	maximized=false;

	if [ ${BASH_REMATCH[5]} -eq 1920 ]; then
		`wmctrl -i -r ${BASH_REMATCH[1]} -b remove,maximized_horz`;

		maximized=true;
	fi;

	`wmctrl -i -r ${BASH_REMATCH[1]} -e 0,${BASH_REMATCH[3]},${BASH_REMATCH[4]},${BASH_REMATCH[5]},${BASH_REMATCH[6]}`;


	if [ "$maximized" = true ]; then
		`wmctrl -i -r ${BASH_REMATCH[1]} -b add,maximized_horz`;
	fi;
done;

Offline

#6 2016-10-08 15:22:06

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 78,611

Re: Save the window positions and move windows via shell script

echo "This script must be run as root"

This looks incredibly suspicious - and is probably wrong.
The script should run as whoever has the X authority - what is better not UID 0.

Offline

#7 2016-10-08 16:09:34

Observer
Member
Registered: 2016-03-01
Posts: 16

Re: Save the window positions and move windows via shell script

This check is preparative for the later use case. In the final script I must work with systemctl and start services.

Offline

#8 2016-10-08 16:48:41

Omar007
Member
Registered: 2015-04-09
Posts: 368

Re: Save the window positions and move windows via shell script

Then you probably should just run those commands as root, not all the others as well (e.g. prefix just those commands with sudo).

Last edited by Omar007 (2016-10-08 16:49:17)

Offline

Board footer

Powered by FluxBB