1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-19 12:28:22 +01:00

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 <crmafra@gmail.com>
This commit is contained in:
Doug Torrance
2014-09-20 22:56:22 -05:00
committed by Carlos R. Mafra
parent 5f6f73e178
commit df49061865
3 changed files with 66 additions and 1 deletions

View File

@@ -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 */

View File

@@ -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,

View File

@@ -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,