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.
---
 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 53d2eaf..a93a64d 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 72c8b6f..7349443 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 c88875b..6899a86 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,
-- 
1.9.1


-- 
To unsubscribe, send mail to wmaker-dev-unsubscr...@lists.windowmaker.org.

Reply via email to