You are not logged in.

1

Wednesday, March 24th 2010, 3:30pm

Button to swap windows between two monitors with extended desktop.

The configuration:
When we have two or more monitors and we want to swap windows between them instead of dragging.
The idea:
To have a possibility adding a button on the title bar if we desire this feature.
Where:
In system settings, where we add or remove buttons to title bar.


Two screenshots illustrating the idea



The magic button dragged to the title bar


I think this could be a great feature. Or to add a configurable button where we associate a custom command could be great then could add new personal features to desktop behavior.

THE CODE:
The code is already written by Judlien Bramary and it works. Just we need is the button:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/* swapmonitor is an XLib based helper to swap windows between
the two monitors of a Xinerama-like dislpay */
/*

Copyright (C) 2008 - Julien Bramary

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see .

*/

#include 
#include 
#include 
#include 
#include 

#define verbose 0
#define v_printf(...) if (verbose) { \
fprintf(stderr, __VA_ARGS__); \
}

int main (int argc, char **argv) {

int ret = EXIT_SUCCESS;
int x, y, new_x;
int actual_format_return;

unsigned long nitems_return;
unsigned long bytes_after_return;
unsigned long grflags;
long mask;

unsigned char *data;

Display *disp;
Window win = (Window)0;
Window w_dum = (Window)0;
XWindowAttributes activ_atr;
XWindowAttributes root_atr;
XEvent event;

// Check we can get the display to avoid looking stupid later
if (! (disp = XOpenDisplay(NULL))) {
fputs("Cannot open display.\n", stderr);
return EXIT_FAILURE;
}

// Define Atoms
Atom ret_atom = (Atom)0;
Atom maximised_vertically = XInternAtom( disp, "_NET_WM_STATE_MAXIMIZED_VERT", False );
Atom maximised_horizontally = XInternAtom( disp, "_NET_WM_STATE_MAXIMIZED_HORZ", False );

// Get active window
XGetWindowProperty(disp, DefaultRootWindow(disp), XInternAtom(disp, "_NET_ACTIVE_WINDOW", False),
0, 1024, False, XA_WINDOW, &ret_atom,
&actual_format_return, &nitems_return, &bytes_after_return, &data);

win = *((Window *)data);
XFree(data);

// Get coordinates
XGetWindowAttributes(disp, win, &activ_atr);
XTranslateCoordinates (disp, win, activ_atr.root, activ_atr.x, activ_atr.y, &x, &y, &w_dum);


v_printf("%ux%u @ (%d,%d)\n", activ_atr.width, activ_atr.height, x, y);

// Get resolution
XGetWindowAttributes(disp, activ_atr.root, &root_atr);
v_printf("Resolution: %ux%u\n", root_atr.width, root_atr.height);


// Determine maximised state
Bool isMaxVert = False;
Bool isMaxHorz = False;
XGetWindowProperty (disp, win, XInternAtom(disp, "_NET_WM_STATE", False),
0, 1024, False, XA_ATOM, &ret_atom, 
&actual_format_return, &nitems_return, &bytes_after_return, &data);


unsigned long *buff = (unsigned long *)data;
for (; nitems_return; nitems_return--) {
if ( *buff == (unsigned long) maximised_vertically) {
isMaxVert = True;
v_printf("Is Vertically maximised\n");
}
else if ( *buff == (unsigned long) maximised_horizontally) {
isMaxHorz = True;
v_printf("Is Horizontally maximised\n");
}
buff++;
}
XFree(data);

// Calculate new X
new_x = ( 2*x + activ_atr.width - root_atr.width > 0 ) ? 
x - root_atr.width/2 : x + root_atr.width/2;


// Ensure that the window fits in the new Screen
grflags = StaticGravity;
if (new_x < 0) {
v_printf ("Fixing left x\n");
grflags = NorthWestGravity;
new_x = 0;
}
if (new_x + activ_atr.width > root_atr.width) {
v_printf ("Fixing right x\n");
grflags = NorthEastGravity;
new_x = root_atr.width - activ_atr.width;
}

v_printf("%ux%u @ (%d,%d)\n", activ_atr.width, activ_atr.height, new_x, y);

// Only move x
grflags |= 0x100;

mask = SubstructureRedirectMask | SubstructureNotifyMask;
event.xclient.type = ClientMessage;
event.xclient.serial = 0;
event.xclient.send_event = True;
event.xclient.window = win;
event.xclient.format = 32;


// De-maximise first, seems necessary in some cases
event.xclient.message_type = XInternAtom(disp, "_NET_WM_STATE", False);
event.xclient.data.l[0] = (unsigned long)0;
event.xclient.data.l[1] = isMaxVert ? (unsigned long)maximised_vertically : 0;
event.xclient.data.l[2] = isMaxHorz ? (unsigned long)maximised_horizontally : 0;

XSendEvent(disp, DefaultRootWindow(disp), False, mask, &event);


// actual move
event.xclient.message_type = XInternAtom(disp, "_NET_MOVERESIZE_WINDOW", False);
event.xclient.data.l[0] = grflags;
event.xclient.data.l[1] = (unsigned long)new_x;
XSendEvent(disp, DefaultRootWindow(disp), False, mask, &event);


// restore maximisation state
event.xclient.message_type = XInternAtom(disp, "_NET_WM_STATE", False);
event.xclient.data.l[0] = (unsigned long)1;
event.xclient.data.l[1] = isMaxVert ? (unsigned long)maximised_vertically : 0;
event.xclient.data.l[2] = isMaxHorz ? (unsigned long)maximised_horizontally : 0;

XSendEvent(disp, DefaultRootWindow(disp), False, mask, &event);

XCloseDisplay(disp);

return ret;
}

2

Thursday, May 6th 2010, 8:32am

interesting. nice work.

3

Tuesday, November 16th 2010, 8:57am

it's rather usefull.

Similar threads

Used tags

display