From 54aae6c0621a609684c3caa8ba3a5b858215fb18 Mon Sep 17 00:00:00 2001 From: gryf Date: Sun, 15 Jan 2017 20:56:12 +0100 Subject: [PATCH] Enabling moving window in cycles. WindowMaker have a Maximus feature expanded by ability to resize windows to half screen (horizontally and vertically). Although, there was no way to move windows between different heads (while screen is spanned between different monitors - heads - if there was no xinerama used). This patch enables possibility for moving windows between states. Assuming we have a window on first head, maximize left would make the window occupy left half of the screen. Assuming we have another head right of the first head, following scenario will be possible: - maximize right will make window occupy entire free space (just like ordinary maximizing will do) - another maximize right will make window be maximized half right of the first screen - another maximize right will make window be maximized half left on second screen - another maximize right will make window be maximized on second screen - another maximize right will make window be maximized half right on second screen - another maximize right will make no effect So it will cycle between half screen/fullscreen making window to travel from left to right. Same goes for opposite direction. --- src/actions.c | 56 ++++++++++++++++++++++++++++++++++----------------- src/actions.h | 2 +- src/event.c | 3 ++- src/window.c | 2 +- src/winmenu.c | 5 +++-- src/wmspec.c | 15 +++++++++----- 6 files changed, 54 insertions(+), 29 deletions(-) diff --git a/src/actions.c b/src/actions.c index 5adfab49..5ac98c64 100644 --- a/src/actions.c +++ b/src/actions.c @@ -354,7 +354,7 @@ void update_saved_geometry(WWindow *wwin) save_old_geometry(wwin, SAVE_GEOMETRY_X); } -void wMaximizeWindow(WWindow *wwin, int directions) +void wMaximizeWindow(WWindow *wwin, int directions, int head) { unsigned int new_width, new_height, half_scr_width, half_scr_height; int new_x = 0; @@ -388,20 +388,7 @@ void wMaximizeWindow(WWindow *wwin, int directions) totalArea.y2 = scr->scr_height; totalArea.x1 = 0; totalArea.y1 = 0; - usableArea = totalArea; - - if (!(directions & MAX_IGNORE_XINERAMA)) { - WScreen *scr = wwin->screen_ptr; - int head; - - if (directions & MAX_KEYBOARD) - head = wGetHeadForWindow(wwin); - else - head = wGetHeadForPointerLocation(scr); - - usableArea = wGetUsableAreaForHead(scr, head, &totalArea, True); - } - + usableArea = wGetUsableAreaForHead(scr, head, &totalArea, True); /* Only save directions, not kbd or xinerama hints */ directions &= (MAX_HORIZONTAL | MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS); @@ -497,20 +484,51 @@ void handleMaximize(WWindow *wwin, int directions) int requested = directions & (MAX_HORIZONTAL | MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS); int effective = requested ^ current; int flags = directions & ~requested; + int head = wGetHeadForWindow(wwin); + WMPoint p; if (!effective) { /* allow wMaximizeWindow to restore the Maximusized size */ if ((wwin->flags.old_maximized & MAX_MAXIMUS) && !(requested & MAX_MAXIMUS)) - wMaximizeWindow(wwin, MAX_MAXIMUS | flags); - else - wUnmaximizeWindow(wwin); + wMaximizeWindow(wwin, MAX_MAXIMUS | flags, head); + else { + if (requested & MAX_LEFTHALF && current & MAX_LEFTHALF) { + p.x = wwin->frame_x - 100; + p.y = 0; + + if (p.x > 0) { + head = wGetHeadForPoint(wwin->screen_ptr, p); + if (head != wGetHeadForWindow(wwin)) { + effective |= MAX_RIGHTHALF; + effective |= MAX_VERTICAL; + effective &= ~(MAX_HORIZONTAL | MAX_LEFTHALF); + wMaximizeWindow(wwin, effective | flags, head); + } + } + } + else if (requested & MAX_RIGHTHALF && current & MAX_RIGHTHALF) { + p.x = wwin->frame_x + wwin->frame->core->width + 100; + p.y = 0; + head = wGetHeadForPoint(wwin->screen_ptr, p); + if (head != wGetHeadForWindow(wwin)) { + effective |= MAX_LEFTHALF; + effective |= MAX_VERTICAL; + effective &= ~(MAX_HORIZONTAL | MAX_RIGHTHALF); + wMaximizeWindow(wwin, effective | flags, head); + } + } + } /* these alone mean vertical|horizontal toggle */ } else if ((effective == MAX_LEFTHALF) || (effective == MAX_RIGHTHALF) || (effective == MAX_TOPHALF) || (effective == MAX_BOTTOMHALF)) wUnmaximizeWindow(wwin); + else if (requested & MAX_LEFTHALF && current & MAX_RIGHTHALF) + wMaximizeWindow(wwin, (MAX_HORIZONTAL|MAX_VERTICAL), head); + else if (requested & MAX_RIGHTHALF && current & MAX_LEFTHALF) + wMaximizeWindow(wwin, (MAX_HORIZONTAL|MAX_VERTICAL), head); else { if ((requested == (MAX_HORIZONTAL | MAX_VERTICAL)) || (requested == MAX_MAXIMUS)) @@ -552,7 +570,7 @@ void handleMaximize(WWindow *wwin, int directions) effective &= ~(MAX_TOPHALF | MAX_BOTTOMHALF); effective &= ~MAX_MAXIMUS; } - wMaximizeWindow(wwin, effective | flags); + wMaximizeWindow(wwin, effective | flags, head); } } diff --git a/src/actions.h b/src/actions.h index 8390e49c..a15cf488 100644 --- a/src/actions.h +++ b/src/actions.h @@ -57,7 +57,7 @@ void wSelectWindows(WScreen *scr, XEvent *ev); void wSelectWindow(WWindow *wwin, Bool flag); void wUnselectWindows(WScreen *scr); -void wMaximizeWindow(WWindow *wwin, int directions); +void wMaximizeWindow(WWindow *wwin, int directions, int head); void wUnmaximizeWindow(WWindow *wwin); void handleMaximize(WWindow *wwin, int directions); diff --git a/src/event.c b/src/event.c index e7ee074f..54c191fb 100644 --- a/src/event.c +++ b/src/event.c @@ -632,7 +632,8 @@ static void handleMapRequest(XEvent * ev) if (wwin) { wClientSetState(wwin, NormalState, None); if (wwin->flags.maximized) { - wMaximizeWindow(wwin, wwin->flags.maximized); + wMaximizeWindow(wwin, wwin->flags.maximized, + wGetHeadForWindow(wwin)); } if (wwin->flags.shaded) { wwin->flags.shaded = 0; diff --git a/src/window.c b/src/window.c index 532670ce..8945a547 100644 --- a/src/window.c +++ b/src/window.c @@ -2855,7 +2855,7 @@ static void titlebarDblClick(WCoreWindow *sender, void *data, XEvent *event) int ndir = dir ^ wwin->flags.maximized; if (ndir != 0) - wMaximizeWindow(wwin, ndir); + wMaximizeWindow(wwin, ndir, wGetHeadForWindow(wwin)); else wUnmaximizeWindow(wwin); } diff --git a/src/winmenu.c b/src/winmenu.c index c7da09d3..fc63fc6b 100644 --- a/src/winmenu.c +++ b/src/winmenu.c @@ -169,7 +169,7 @@ static void execWindowOptionCommand(WMenu * menu, WMenuEntry * entry) static void execMaximizeCommand(WMenu * menu, WMenuEntry * entry) { WWindow *wwin = (WWindow *) entry->clientdata; - + /* Parameter not used, but tell the compiler that it is ok */ (void) menu; @@ -277,7 +277,8 @@ static void execMenuCommand(WMenu * menu, WMenuEntry * entry) if (wwin->flags.maximized) wUnmaximizeWindow(wwin); else - wMaximizeWindow(wwin, MAX_VERTICAL | MAX_HORIZONTAL); + wMaximizeWindow(wwin, MAX_VERTICAL | MAX_HORIZONTAL, + wGetHeadForWindow(wwin)); break; case MC_SHADE: diff --git a/src/wmspec.c b/src/wmspec.c index 9b56f96f..96ba984e 100644 --- a/src/wmspec.c +++ b/src/wmspec.c @@ -1120,9 +1120,11 @@ static void doStateAtom(WWindow *wwin, Atom state, int set, Bool init) wwin->flags.maximized |= (set ? MAX_VERTICAL : 0); } else { if (set) - wMaximizeWindow(wwin, wwin->flags.maximized | MAX_VERTICAL); + wMaximizeWindow(wwin, wwin->flags.maximized | MAX_VERTICAL, + wGetHeadForWindow(wwin)); else - wMaximizeWindow(wwin, wwin->flags.maximized & ~MAX_VERTICAL); + wMaximizeWindow(wwin, wwin->flags.maximized & ~MAX_VERTICAL, + wGetHeadForWindow(wwin)); } } else if (state == net_wm_state_maximized_horz) { if (set == _NET_WM_STATE_TOGGLE) @@ -1132,9 +1134,11 @@ static void doStateAtom(WWindow *wwin, Atom state, int set, Bool init) wwin->flags.maximized |= (set ? MAX_HORIZONTAL : 0); } else { if (set) - wMaximizeWindow(wwin, wwin->flags.maximized | MAX_HORIZONTAL); + wMaximizeWindow(wwin, wwin->flags.maximized | MAX_HORIZONTAL, + wGetHeadForWindow(wwin)); else - wMaximizeWindow(wwin, wwin->flags.maximized & ~MAX_HORIZONTAL); + wMaximizeWindow(wwin, wwin->flags.maximized & ~MAX_HORIZONTAL, + wGetHeadForWindow(wwin)); } } else if (state == net_wm_state_hidden) { if (set == _NET_WM_STATE_TOGGLE) @@ -1623,7 +1627,8 @@ Bool wNETWMProcessClientMessage(XClientMessageEvent *event) wwin->flags.maximized = maximized; wUnmaximizeWindow(wwin); } else { - wMaximizeWindow(wwin, wwin->flags.maximized); + wMaximizeWindow(wwin, wwin->flags.maximized, + wGetHeadForWindow(wwin)); } } updateStateHint(wwin, False, False);