3
## DP: From: Bert Wesarg <bert.wesarg@googlemail.com>
4
## DP: Subject: [PATCH] keys to move windows to another xinerama screen
5
## DP: New key actions to move a window between xinerama screens. The new position
6
## DP: will be relatively the same as on the old screen. I.e. if the window was
7
## DP: centered, its centered again, if it was in the lower left corner, it will be
8
## DP: again in the lower left corner. Maximazations states will be restored.
9
## DP: Fullscreen too, but this wont work well with mplayer in fullscreen.
12
echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
16
[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
17
patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
20
-patch) patch -p1 ${patch_opts} < $0;;
21
-unpatch) patch -R -p1 ${patch_opts} < $0;;
23
echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
30
diff --git a/src/bindkey.h b/src/bindkey.h
31
index 6ea53b7..29cd228 100644
35
#define defgKeyWinSnapMoveW XK_KP_Left, kfCtrl+kfAlt+kfShift, "Ctrl+Alt+Shift+KP_4"
36
#define defgKeyWinSnapMoveNW XK_KP_Home, kfCtrl+kfAlt+kfShift, "Ctrl+Alt+Shift+KP_7"
37
#define defgKeyWinSmartPlace XK_KP_Begin, kfCtrl+kfAlt+kfShift, "Ctrl+Alt+Shift+KP_5"
38
+#define defgKeyWinScreenPrimary XK_Home, kfCtrl+kfAlt, "Ctrl+Alt+Home"
39
+#define defgKeyWinScreenNext XK_End, kfCtrl+kfAlt, "Ctrl+Alt+Page_Up"
40
+#define defgKeyWinScreenPrev XK_End, kfCtrl+kfAlt, "Ctrl+Alt+Page_Down"
41
+#define defgKeyWinScreen1 0, 0, ""
42
+#define defgKeyWinScreen2 0, 0, ""
43
+#define defgKeyWinScreen3 0, 0, ""
44
+#define defgKeyWinScreen4 0, 0, ""
45
+#define defgKeyWinScreen5 0, 0, ""
46
+#define defgKeyWinScreen6 0, 0, ""
47
+#define defgKeyWinScreen7 0, 0, ""
48
+#define defgKeyWinScreen8 0, 0, ""
49
+#define defgKeyWinScreen9 0, 0, ""
50
+#define defgKeyWinScreen10 0, 0, ""
51
+#define defgKeyWinScreen11 0, 0, ""
52
+#define defgKeyWinScreen12 0, 0, ""
53
#define defgKeySysSwitchNext XK_Tab, kfAlt, "Alt+Tab"
54
#define defgKeySysSwitchLast XK_Tab, kfAlt+kfShift, "Alt+Shift+Tab"
55
#define defgKeySysWinNext XK_Escape, kfAlt, "Alt+Esc"
56
@@ -154,6 +169,21 @@ DEF_WMKEY(gKeyWinSnapMoveSW);
57
DEF_WMKEY(gKeyWinSnapMoveW);
58
DEF_WMKEY(gKeyWinSnapMoveNW);
59
DEF_WMKEY(gKeyWinSmartPlace);
60
+DEF_WMKEY(gKeyWinScreenPrimary);
61
+DEF_WMKEY(gKeyWinScreenNext);
62
+DEF_WMKEY(gKeyWinScreenPrev);
63
+DEF_WMKEY(gKeyWinScreen1);
64
+DEF_WMKEY(gKeyWinScreen2);
65
+DEF_WMKEY(gKeyWinScreen3);
66
+DEF_WMKEY(gKeyWinScreen4);
67
+DEF_WMKEY(gKeyWinScreen5);
68
+DEF_WMKEY(gKeyWinScreen6);
69
+DEF_WMKEY(gKeyWinScreen7);
70
+DEF_WMKEY(gKeyWinScreen8);
71
+DEF_WMKEY(gKeyWinScreen9);
72
+DEF_WMKEY(gKeyWinScreen10);
73
+DEF_WMKEY(gKeyWinScreen11);
74
+DEF_WMKEY(gKeyWinScreen12);
75
DEF_WMKEY(gKeyWinMenu);
76
DEF_WMKEY(gKeySysSwitchNext);
77
DEF_WMKEY(gKeySysSwitchLast);
78
diff --git a/src/default.h b/src/default.h
79
index e967e64..c373a32 100644
82
@@ -409,6 +409,21 @@ cfoption icewm_preferences[] = {
83
OKV("KeyWinArrangeW", gKeyWinArrangeW, ""),
84
OKV("KeyWinArrangeNW", gKeyWinArrangeNW, ""),
85
OKV("KeyWinArrangeC", gKeyWinArrangeC, ""),
86
+ OKV("KeyWinScreenPrimary", gKeyWinScreenPrimary, "Move current window to the primary Xinerama screen"),
87
+ OKV("KeyWinScreenNext", gKeyWinScreenNext, "Move current window to the next Xinerama screen"),
88
+ OKV("KeyWinScreenPrev", gKeyWinScreenPrev, "Move current window to the previous Xinerama screen"),
89
+ OKV("KeyWinScreen1", gKeyWinScreen1, "Move current window to the first Xinerama screen"),
90
+ OKV("KeyWinScreen2", gKeyWinScreen2, "Move current window to the second Xinerama screen"),
91
+ OKV("KeyWinScreen3", gKeyWinScreen3, "Move current window to the 3rd Xinerama screen"),
92
+ OKV("KeyWinScreen4", gKeyWinScreen4, "Move current window to the 4th Xinerama screen"),
93
+ OKV("KeyWinScreen5", gKeyWinScreen5, "Move current window to the 5th Xinerama screen"),
94
+ OKV("KeyWinScreen6", gKeyWinScreen6, "Move current window to the 6th Xinerama screen"),
95
+ OKV("KeyWinScreen7", gKeyWinScreen7, "Move current window to the 7th Xinerama screen"),
96
+ OKV("KeyWinScreen8", gKeyWinScreen8, "Move current window to the 8th Xinerama screen"),
97
+ OKV("KeyWinScreen9", gKeyWinScreen9, "Move current window to the 9th Xinerama screen"),
98
+ OKV("KeyWinScreen10", gKeyWinScreen10, "Move current window to the 10th Xinerama screen"),
99
+ OKV("KeyWinScreen11", gKeyWinScreen11, "Move current window to the 11th Xinerama screen"),
100
+ OKV("KeyWinScreen12", gKeyWinScreen12, "Move current window to the 12th Xinerama screen"),
101
OKV("KeySysSwitchNext", gKeySysSwitchNext, ""),
102
OKV("KeySysSwitchLast", gKeySysSwitchLast, ""),
103
OKV("KeySysWinNext", gKeySysWinNext, ""),
104
diff --git a/src/movesize.cc b/src/movesize.cc
105
index fa15075..51df8fb 100644
106
--- a/src/movesize.cc
107
+++ b/src/movesize.cc
108
@@ -830,6 +830,36 @@ bool YFrameWindow::handleKey(const XKeyEvent &key) {
109
setCurrentPositionOuter(newX, newY);
112
+ } else if (IS_WMKEY(k, vm, gKeyWinScreenPrimary)) {
113
+ if (canMove()) moveToScreen(-1);
114
+ } else if (IS_WMKEY(k, vm, gKeyWinScreenNext)) {
115
+ if (canMove()) moveToScreen(-2);
116
+ } else if (IS_WMKEY(k, vm, gKeyWinScreenPrev)) {
117
+ if (canMove()) moveToScreen(-3);
118
+ } else if (IS_WMKEY(k, vm, gKeyWinScreen1)) {
119
+ if (canMove()) moveToScreen(0);
120
+ } else if (IS_WMKEY(k, vm, gKeyWinScreen2)) {
121
+ if (canMove()) moveToScreen(1);
122
+ } else if (IS_WMKEY(k, vm, gKeyWinScreen3)) {
123
+ if (canMove()) moveToScreen(2);
124
+ } else if (IS_WMKEY(k, vm, gKeyWinScreen4)) {
125
+ if (canMove()) moveToScreen(3);
126
+ } else if (IS_WMKEY(k, vm, gKeyWinScreen5)) {
127
+ if (canMove()) moveToScreen(4);
128
+ } else if (IS_WMKEY(k, vm, gKeyWinScreen6)) {
129
+ if (canMove()) moveToScreen(5);
130
+ } else if (IS_WMKEY(k, vm, gKeyWinScreen7)) {
131
+ if (canMove()) moveToScreen(6);
132
+ } else if (IS_WMKEY(k, vm, gKeyWinScreen8)) {
133
+ if (canMove()) moveToScreen(7);
134
+ } else if (IS_WMKEY(k, vm, gKeyWinScreen9)) {
135
+ if (canMove()) moveToScreen(8);
136
+ } else if (IS_WMKEY(k, vm, gKeyWinScreen10)) {
137
+ if (canMove()) moveToScreen(9);
138
+ } else if (IS_WMKEY(k, vm, gKeyWinScreen11)) {
139
+ if (canMove()) moveToScreen(10);
140
+ } else if (IS_WMKEY(k, vm, gKeyWinScreen12)) {
141
+ if (canMove()) moveToScreen(11);
142
} else if (isIconic() || isRollup()) {
143
if (k == XK_Return || k == XK_KP_Enter) {
145
diff --git a/src/wmframe.cc b/src/wmframe.cc
146
index 5dc8ba2..2d35bdb 100644
149
@@ -591,6 +591,21 @@ void YFrameWindow::grabKeys() {
150
GRAB_WMKEY(gKeyWinSnapMoveW);
151
GRAB_WMKEY(gKeyWinSnapMoveNW);
152
GRAB_WMKEY(gKeyWinSmartPlace);
153
+ GRAB_WMKEY(gKeyWinScreenPrimary);
154
+ GRAB_WMKEY(gKeyWinScreenNext);
155
+ GRAB_WMKEY(gKeyWinScreenPrev);
156
+ GRAB_WMKEY(gKeyWinScreen1);
157
+ GRAB_WMKEY(gKeyWinScreen2);
158
+ GRAB_WMKEY(gKeyWinScreen3);
159
+ GRAB_WMKEY(gKeyWinScreen4);
160
+ GRAB_WMKEY(gKeyWinScreen5);
161
+ GRAB_WMKEY(gKeyWinScreen6);
162
+ GRAB_WMKEY(gKeyWinScreen7);
163
+ GRAB_WMKEY(gKeyWinScreen8);
164
+ GRAB_WMKEY(gKeyWinScreen9);
165
+ GRAB_WMKEY(gKeyWinScreen10);
166
+ GRAB_WMKEY(gKeyWinScreen11);
167
+ GRAB_WMKEY(gKeyWinScreen12);
169
container()->regrabMouse();
171
@@ -3428,6 +3443,147 @@ int YFrameWindow::getScreen() {
172
return manager->getScreenForRect(nx, ny, nw, nh);
175
+void YFrameWindow::moveToScreen(int newScreen) {
176
+ int oldScreen = getScreen();
178
+ /* handle special screen num for primary/next/prev */
179
+ if (newScreen == -1)
180
+ newScreen = xineramaPrimaryScreen;
181
+ else if (newScreen == -2)
182
+ newScreen = manager->getNextScreen(oldScreen);
183
+ else if (newScreen == -3)
184
+ newScreen = manager->getPrevScreen(oldScreen);
186
+ newScreen = manager->verifyScreen(newScreen, oldScreen);
188
+ if (newScreen == oldScreen)
191
+ MSG(("moveToScreen: %d => %d", oldScreen, newScreen));
193
+ long fOldState = fWinState;
194
+ setState(WinStateRollup |
196
+ WinStateMaximizedVert |
197
+ WinStateMaximizedHoriz |
198
+ WinStateMinimized |
199
+ WinStateFullscreen, 0);
201
+ int oldScreenX1, oldScreenX2, oldScreenY1, oldScreenY2;
202
+ manager->getWorkArea(&oldScreenX1, &oldScreenY1, &oldScreenX2, &oldScreenY2, oldScreen);
203
+ MSG(("moveToScreen: [%+5d,%+5d]x[%+5d,%+5d]", oldScreenX1, oldScreenX2, oldScreenY1, oldScreenY2));
205
+ int newScreenX1, newScreenX2, newScreenY1, newScreenY2;
206
+ manager->getWorkArea(&newScreenX1, &newScreenY1, &newScreenX2, &newScreenY2, newScreen);
207
+ MSG(("moveToScreen: [%+5d,%+5d]x[%+5d,%+5d]", newScreenX1, newScreenX2, newScreenY1, newScreenY2));
209
+ /* remove and remember border{X,Y} */
210
+ bool borderLeft = false,
211
+ borderRight = false,
213
+ borderBottom = false;
215
+ oldX2 = x() + width(),
217
+ oldY2 = y() + height();
219
+ MSG(("moveToScreen: [%+5d,%+5d]x[%+5d,%+5d]", oldX1, oldX2, oldY1, oldY2));
221
+ if (oldX1 == (oldScreenX1 - borderX())) {
222
+ oldX1 = oldScreenX1;
225
+ if (oldX2 == (oldScreenX2 + borderX())) {
226
+ oldX2 = oldScreenX2;
227
+ borderRight = true;
229
+ if (oldY1 == (oldScreenY1 - borderY())) {
230
+ oldY1 = oldScreenY1;
233
+ if (oldY2 == (oldScreenY2 + borderY())) {
234
+ oldY2 = oldScreenY2;
235
+ borderBottom = true;
238
+ MSG(("moveToScreen: [%+5d,%+5d]x[%+5d,%+5d]", oldX1, oldX2, oldY1, oldY2));
240
+ int oldScreenSpaceLeft,
241
+ oldScreenSpaceRight,
243
+ oldScreenSpaceBottom;
244
+ oldScreenSpaceLeft = oldX1 - oldScreenX1;
245
+ oldScreenSpaceRight = oldScreenX2 - oldX2;
246
+ oldScreenSpaceTop = oldY1 - oldScreenY1;
247
+ oldScreenSpaceBottom = oldScreenY2 - oldY2;
249
+ MSG(("moveToScreen: %+5d,%+5d ; %+5d,%+5d",
250
+ oldScreenSpaceLeft,
251
+ oldScreenSpaceRight,
253
+ oldScreenSpaceBottom));
255
+ double horizRatio, vertRatio;
256
+ horizRatio = (oldScreenSpaceLeft + oldScreenSpaceRight)
257
+ ? (double)oldScreenSpaceLeft
258
+ / (oldScreenSpaceLeft + oldScreenSpaceRight)
260
+ vertRatio = (oldScreenSpaceTop + oldScreenSpaceBottom)
261
+ ? (double)oldScreenSpaceTop
262
+ / (oldScreenSpaceTop + oldScreenSpaceBottom)
265
+ MSG(("moveToScreen: %+5.2f ; %+5.2f", horizRatio, vertRatio));
267
+ int newScreenHorizSpace, newScreenVertSpace;
268
+ newScreenHorizSpace = (newScreenX2 - newScreenX1) - (oldX2 - oldX1);
269
+ newScreenVertSpace = (newScreenY2 - newScreenY1) - (oldY2 - oldY1);
271
+ MSG(("moveToScreen: %+5d ; %+5d", newScreenHorizSpace, newScreenVertSpace));
273
+ int newScreenSpaceLeft, newScreenSpaceTop;
274
+ newScreenSpaceLeft = (int)(newScreenHorizSpace * horizRatio);
275
+ newScreenSpaceTop = (int)(newScreenVertSpace * vertRatio);
277
+ MSG(("moveToScreen: %+5d,%+5d ; %+5d,%+5d",
278
+ newScreenSpaceLeft,
279
+ newScreenHorizSpace - newScreenSpaceLeft,
281
+ newScreenVertSpace - newScreenSpaceTop));
283
+ int newX1, newX2, newY1, newY2;
284
+ newX1 = newScreenX1 + newScreenSpaceLeft;
285
+ newY1 = newScreenY1 + newScreenSpaceTop;
287
+ /* re-add remembered border{X,Y} */
288
+ /* this should not work for (borderLeft && borderRight) or
289
+ (borderTop && borderBottom) */
291
+ newX1 -= borderX();
292
+ oldX1 -= borderX();
295
+ newX1 += borderX();
296
+ oldX1 += borderX();
299
+ newY1 -= borderY();
300
+ oldY1 -= borderY();
302
+ if (borderBottom) {
303
+ newY1 += borderY();
304
+ oldY1 += borderY();
307
+ newX2 = newX1 + (oldX2 - oldX1);
308
+ newY2 = newY1 + (oldY2 - oldY1);
310
+ MSG(("moveToScreen: [%+5d,%+5d]x[%+5d,%+5d]\n", newX1, newX2, newY1, newY2));
311
+ setCurrentPositionOuter(newX1, newY1);
313
+ setState(fOldState, fOldState);
316
void YFrameWindow::wmArrange(int tcb, int lcr) {
317
int mx, my, Mx, My, newX = 0, newY = 0;
319
diff --git a/src/wmframe.h b/src/wmframe.h
320
index bfa3b28..f2a39fa 100644
323
@@ -436,6 +436,13 @@ public:
328
+ primaryScreen = -1,
332
+ void moveToScreen(int newScreen = -1);
334
long getOldLayer() { return fOldLayer; }
335
void saveOldLayer() { fOldLayer = fWinActiveLayer; }
337
diff --git a/src/wmmgr.cc b/src/wmmgr.cc
338
index 50e7bfa..5c5a8c7 100644
341
@@ -1899,6 +1899,47 @@ void YWindowManager::getWorkArea(const YFrameWindow *frame,
345
+void YWindowManager::getWorkArea(int *mx, int *my, int *Mx, int *My, int xiscreen, int ws) const
347
+ bool whole = false;
350
+ ws = activeWorkspace();
352
+ if (ws < 0 || ws >= fWorkAreaCount)
362
+/// TODO #warning "rewrite workarea determine code (per workspace)"
364
+ *mx = fWorkArea[ws].fMinX;
365
+ *my = fWorkArea[ws].fMinY;
366
+ *Mx = fWorkArea[ws].fMaxX;
367
+ *My = fWorkArea[ws].fMaxY;
371
+ if (xiscreen != -1) {
372
+ int dx, dy, dw, dh;
373
+ manager->getScreenGeometry(&dx, &dy, &dw, &dh, xiscreen);
386
void YWindowManager::getWorkAreaSize(const YFrameWindow *frame, int *Mw,int *Mh) {
388
manager->getWorkArea(frame, &mx, &my, &Mx, &My);
389
diff --git a/src/wmmgr.h b/src/wmmgr.h
390
index 5bc8060..4067f4c 100644
393
@@ -94,6 +94,7 @@ public:
395
void getWorkArea(const YFrameWindow *frame, int *mx, int *my, int *Mx, int *My, int xiscreen = -1) const;
396
void getWorkAreaSize(const YFrameWindow *frame, int *Mw,int *Mh);
397
+ void getWorkArea(int *mx, int *my, int *Mx, int *My, int xiscreen, int ws = -1) const;
399
int calcCoverage(bool down, YFrameWindow *frame, int x, int y, int w, int h);
400
void tryCover(bool down, YFrameWindow *frame, int x, int y, int w, int h,
401
diff --git a/src/ywindow.cc b/src/ywindow.cc
402
index 82ed4a7..ca96f9f 100644
405
@@ -1963,3 +1963,48 @@ int YDesktop::getScreenForRect(int x, int y, int width, int height) {
410
+int YDesktop::verifyScreen(int xiscreen, int fallback) {
411
+ if (fallback == -1)
412
+ fallback = xineramaPrimaryScreen;
414
+ for (int s = 0; s < xiHeads; s++) {
415
+ if (xiInfo[s].screen_number == xiscreen) {
423
+int YDesktop::getNextScreen(int xiscreen) {
425
+ if (xiscreen == -1)
426
+ xiscreen = xineramaPrimaryScreen;
427
+ for (int s = 0; s < xiHeads; s++) {
428
+ if (xiInfo[s].screen_number == xiscreen) {
432
+ return xiInfo[s].screen_number;
436
+ return xineramaPrimaryScreen;
439
+int YDesktop::getPrevScreen(int xiscreen) {
441
+ if (xiscreen == -1)
442
+ xiscreen = xineramaPrimaryScreen;
443
+ for (int s = 0; s < xiHeads; s++) {
444
+ if (xiInfo[s].screen_number == xiscreen) {
448
+ return xiInfo[s].screen_number;
452
+ return xineramaPrimaryScreen;
454
diff --git a/src/ywindow.h b/src/ywindow.h
455
index 7441624..7818408 100644
458
@@ -288,6 +288,9 @@ public:
459
int *width, int *height,
461
int getScreenForRect(int x, int y, int width, int height);
462
+ int verifyScreen(int xiscreen, int fallback = -1);
463
+ int getNextScreen(int xiscreen = -1);
464
+ int getPrevScreen(int xiscreen = -1);
466
virtual void grabKeys() {}
469
tg: (b1df5f6..) bw/move-to-screen (depends on: icewm-1.2)