1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-18 20:10:29 +01:00

support moving window between heads using keyboard

Window Maker allows to perform practically all operations with windows
using only keyboard. One of the actions so far which required using
mouse was dragging window from one head (monitor) to another.

This patch introduces support for keyboard shortcuts. These shortcuts
move windows in circular fashion (if you have 3 and more monitors).

In case of 2 or 3 monitors arranged horizontally - window will just move
right/left.

In case of 3x3 setup - it is impossible to move window to central
monitor with keyboard.

- preserves window position and size (if display sizes are same)
- otherwise tries to fit window to smaller display
This commit is contained in:
Gaspar Chilingarov
2018-09-16 16:55:16 +03:00
committed by Carlos R. Mafra
parent d13b78bdde
commit 8b919b0d33
5 changed files with 104 additions and 0 deletions

View File

@@ -148,6 +148,10 @@ static const struct {
{ "WindowShortcut9Key", N_("Shortcut for window 9") },
{ "WindowShortcut10Key", N_("Shortcut for window 10") },
/* Head Selection */
{ "MoveTo12to6Head", N_("Move to right/bottom/left/top head") },
{ "MoveTo6to12Head", N_("Move to left/top/right/bottom head") },
/* Misc. */
{ "WindowRelaunchKey", N_("Launch new instance of application") },
{ "ScreenSwitchKey", N_("Switch to Next Screen/Monitor") },

View File

@@ -669,6 +669,91 @@ void handleMaximize(WWindow *wwin, int directions)
}
}
/* Moving window between heads
*
* Window is moved between all avaiable heads for current screen in
* requested direction.
*
* If heads have different sizes, window position will be adjusted to be inside
* screen. Window will be unmaximized on move, so that it can be immediately be
* maximixed by another shortcut.
*
*
* direction = 0 means move clock-wise from 12h position to 6h
* (first try moving right, then bottom, then left, then up)
* direction = 1 means move clock-wise from 6h position to 12h
* (first try moving left, then up, then right, then bottom)
*
*
* As side effect this mean if you have 9 monitors - you will not be able to
* move window into central cell without mouse.
*
* For common cases with 1 or 2 extra monitors this should work just fine.
*
* */
void moveBetweenHeads(WWindow *wwin, int direction)
{
int head = wGetHeadForWindow(wwin);
int destHead = -1;
unsigned int new_width, new_height;
int offsetX, newX = 0;
int offsetY, newY = 0;
WArea totalArea, oldHeadArea, destHeadArea;
WScreen *scr = wwin->screen_ptr;
int try_movements[2][4] = {
{DIRECTION_RIGHT, DIRECTION_DOWN, DIRECTION_LEFT, DIRECTION_UP},
{DIRECTION_LEFT, DIRECTION_UP, DIRECTION_RIGHT, DIRECTION_DOWN}
};
/* loop through directions array and try movements until one works */
for (int try_movement_idx = 0;
destHead == -1 && try_movement_idx < 4; try_movement_idx++) {
destHead = wGetHeadRelativeToCurrentHead(wwin->screen_ptr,
head, try_movements[direction][try_movement_idx]);
}
if (destHead != -1) {
totalArea.x1 = 0;
totalArea.y1 = 0;
totalArea.x2 = scr->scr_width;
totalArea.y2 = scr->scr_height;
oldHeadArea = wGetUsableAreaForHead(scr, head, &totalArea, True);
destHeadArea = wGetUsableAreaForHead(scr, destHead, &totalArea, True);
offsetX = wwin->frame_x - oldHeadArea.x1;
offsetY = wwin->frame_y - oldHeadArea.y1;
newX = destHeadArea.x1 + offsetX;
newY = destHeadArea.y1 + offsetY;
new_width = wwin->client.width;
new_height = wwin->client.height;
/* try to brind window inside head coordinates */
if (newX > destHeadArea.x2)
newX = destHeadArea.x2 - wwin->client.width;
if (newX < destHeadArea.x1)
newX = destHeadArea.x1;
if (newY > destHeadArea.y2)
newY = destHeadArea.y2 - wwin->client.height;
if (newY < destHeadArea.y1)
newY = destHeadArea.y1;
/* unset maximization state */
wwin->flags.maximized = 0;
wWindowConfigure(wwin, newX, newY, new_width, new_height);
}
return;
}
/* the window boundary coordinates */
typedef struct {
int left;

View File

@@ -770,6 +770,10 @@ WDefaultEntry optionList[] = {
NULL, getKeybind, setKeyGrab, NULL, NULL},
{"WindowShortcut10Key", "None", (void *)WKBD_WINDOW10,
NULL, getKeybind, setKeyGrab, NULL, NULL},
{"MoveTo12to6Head", "None", (void *)WKBD_MOVE_12_TO_6_HEAD,
NULL, getKeybind, setKeyGrab, NULL, NULL},
{"MoveTo6to12Head", "None", (void *)WKBD_MOVE_6_TO_12_HEAD,
NULL, getKeybind, setKeyGrab, NULL, NULL},
{"WindowRelaunchKey", "None", (void *)WKBD_RELAUNCH,
NULL, getKeybind, setKeyGrab, NULL, NULL},
{"ScreenSwitchKey", "None", (void *)WKBD_SWITCH_SCREEN,

View File

@@ -1802,6 +1802,13 @@ static void handleKeyPress(XEvent * event)
break;
case WKBD_MOVE_12_TO_6_HEAD:
case WKBD_MOVE_6_TO_12_HEAD:
if (wwin)
moveBetweenHeads(wwin, command - WKBD_MOVE_12_TO_6_HEAD);
break;
case WKBD_RELAUNCH:
if (ISMAPPED(wwin) && ISFOCUSED(wwin))
(void) RelaunchWindow(wwin);

View File

@@ -132,6 +132,10 @@ enum {
WKBD_WINDOW9,
WKBD_WINDOW10,
/* shortcuts to move window between heads */
WKBD_MOVE_12_TO_6_HEAD,
WKBD_MOVE_6_TO_12_HEAD,
/* launch a new instance of the active window */
WKBD_RELAUNCH,