From df4906186525c25781320c58a4d22168eae0c39c Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Sat, 20 Sep 2014 22:56:22 -0500 Subject: [PATCH] wmaker: Add window snapping feature. This patch adds the ability to "snap" a window to one side of the screen by dragging it to that side. It is enabled by setting WindowSnapping = "YES" in ~/GNUstep/Defaults/WindowMaker. Note that window snapping is automatically disabled if DontLinkWorkspaces = "NO", as this feature also involves dragging a window to one side of the screen. Signed-off-by: Carlos R. Mafra --- src/WindowMaker.h | 1 + src/defaults.c | 2 ++ src/moveres.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/WindowMaker.h b/src/WindowMaker.h index 9af3a394..31c67d26 100644 --- a/src/WindowMaker.h +++ b/src/WindowMaker.h @@ -352,6 +352,7 @@ extern struct WPreferences { char no_dithering; /* use dithering or not */ char no_animations; /* enable/disable animations */ char no_autowrap; /* wrap workspace when window is moved to the edge */ + char window_snapping; /* enable window snapping */ char highlight_active_app; /* show the focused app by highlighting its icon */ char auto_arrange_icons; /* automagically arrange icons */ diff --git a/src/defaults.c b/src/defaults.c index 72c8b6f3..7349443e 100644 --- a/src/defaults.c +++ b/src/defaults.c @@ -450,6 +450,8 @@ WDefaultEntry optionList[] = { &wPreferences.no_animations, getBool, NULL, NULL, NULL}, {"DontLinkWorkspaces", "NO", NULL, &wPreferences.no_autowrap, getBool, NULL, NULL, NULL}, + {"WindowSnapping", "NO", NULL, + &wPreferences.window_snapping, getBool, NULL, NULL, NULL}, {"HighlightActiveApp", "YES", NULL, &wPreferences.highlight_active_app, getBool, NULL, NULL, NULL}, {"AutoArrangeIcons", "NO", NULL, diff --git a/src/moveres.c b/src/moveres.c index c88875b7..6899a866 100644 --- a/src/moveres.c +++ b/src/moveres.c @@ -588,6 +588,8 @@ typedef struct { int calcX, calcY; /* calculated position of window */ int omouseX, omouseY; /* old mouse position */ int mouseX, mouseY; /* last known position of the pointer */ + + enum {SNAP_NONE, SNAP_LEFT, SNAP_RIGHT} snap; } MoveData; #define WTOP(w) (w)->frame_y @@ -829,6 +831,8 @@ static void initMoveData(WWindow * wwin, MoveData * data) data->winWidth = wwin->frame->core->width + (HAS_BORDER_WITH_SELECT(wwin) ? 2 * wwin->screen_ptr->frame_border_width : 0); data->winHeight = wwin->frame->core->height + (HAS_BORDER_WITH_SELECT(wwin) ? 2 * wwin->screen_ptr->frame_border_width : 0); + + data->snap = SNAP_NONE; } static Bool checkWorkspaceChange(WWindow * wwin, MoveData * data, Bool opaqueMove) @@ -1642,12 +1646,48 @@ int wMouseMoveWindow(WWindow * wwin, XEvent * ev) break; case MotionNotify: + if (IS_RESIZABLE(wwin) && wPreferences.window_snapping && wPreferences.no_autowrap) { + if (moveData.snap == SNAP_LEFT && moveData.mouseX > 1) { + moveData.snap = SNAP_NONE; + drawTransparentFrame(wwin, 0, 0, scr->scr_width/2, scr->scr_height); + } + if (moveData.snap == SNAP_RIGHT && moveData.mouseX < scr->scr_width - 2) { + moveData.snap = SNAP_NONE; + drawTransparentFrame(wwin, scr->scr_width/2, 0, scr->scr_width/2, + scr->scr_height); + } + if (moveData.snap == SNAP_NONE) { + if (moveData.mouseX <= 1) { + moveData.snap = SNAP_LEFT; + drawTransparentFrame(wwin, 0, 0, scr->scr_width/2, + scr->scr_height); + } + if (moveData.mouseX >= scr->scr_width - 2) { + moveData.snap = SNAP_RIGHT; + drawTransparentFrame(wwin, scr->scr_width/2, 0, scr->scr_width/2, + scr->scr_height); + } + } + } + if (started) { + if (moveData.snap == SNAP_LEFT) + drawTransparentFrame(wwin, 0, 0, scr->scr_width/2, scr->scr_height); + if (moveData.snap == SNAP_RIGHT) + drawTransparentFrame(wwin, scr->scr_width/2, 0, scr->scr_width/2, + scr->scr_height); + updateWindowPosition(wwin, &moveData, scr->selected_windows == NULL && wPreferences.edge_resistance > 0, opaqueMove, event.xmotion.x_root, event.xmotion.y_root); + if (moveData.snap == SNAP_LEFT) + drawTransparentFrame(wwin, 0, 0, scr->scr_width/2, scr->scr_height); + if (moveData.snap == SNAP_RIGHT) + drawTransparentFrame(wwin, scr->scr_width/2, 0, scr->scr_width/2, + scr->scr_height); + if (!warped && !wPreferences.no_autowrap) { int oldWorkspace = w_global.workspace.current; @@ -1703,6 +1743,7 @@ int wMouseMoveWindow(WWindow * wwin, XEvent * ev) showPosition(wwin, moveData.realX, moveData.realY); } } + break; case ButtonPress: @@ -1712,7 +1753,28 @@ int wMouseMoveWindow(WWindow * wwin, XEvent * ev) if (event.xbutton.button != ev->xbutton.button) break; - if (started) { + if (moveData.snap != SNAP_NONE) { + if (moveData.snap == SNAP_LEFT) { + /* erase frames */ + if (!opaqueMove) + drawFrames(wwin, scr->selected_windows, + moveData.realX - wwin->frame_x, + moveData.realY - wwin->frame_y); + drawTransparentFrame(wwin, 0, 0, scr->scr_width/2, scr->scr_height); + handleMaximize(wwin, MAX_VERTICAL | MAX_LEFTHALF); + } + if (moveData.snap == SNAP_RIGHT) { + /* erase frames */ + if (!opaqueMove) + drawFrames(wwin, scr->selected_windows, + moveData.realX - wwin->frame_x, + moveData.realY - wwin->frame_y); + drawTransparentFrame(wwin, scr->scr_width/2, 0, scr->scr_width/2, + scr->scr_height); + handleMaximize(wwin, MAX_VERTICAL | MAX_RIGHTHALF); + } + moveData.snap = SNAP_NONE; + } else if (started) { XEvent e; if (!opaqueMove) { drawFrames(wwin, scr->selected_windows, -- 2.11.4.GIT