mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-19 20:38:08 +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:
committed by
Carlos R. Mafra
parent
5f6f73e178
commit
df49061865
@@ -352,6 +352,7 @@ extern struct WPreferences {
|
|||||||
char no_dithering; /* use dithering or not */
|
char no_dithering; /* use dithering or not */
|
||||||
char no_animations; /* enable/disable animations */
|
char no_animations; /* enable/disable animations */
|
||||||
char no_autowrap; /* wrap workspace when window is moved to the edge */
|
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 highlight_active_app; /* show the focused app by highlighting its icon */
|
||||||
char auto_arrange_icons; /* automagically arrange icons */
|
char auto_arrange_icons; /* automagically arrange icons */
|
||||||
|
|||||||
@@ -450,6 +450,8 @@ WDefaultEntry optionList[] = {
|
|||||||
&wPreferences.no_animations, getBool, NULL, NULL, NULL},
|
&wPreferences.no_animations, getBool, NULL, NULL, NULL},
|
||||||
{"DontLinkWorkspaces", "NO", NULL,
|
{"DontLinkWorkspaces", "NO", NULL,
|
||||||
&wPreferences.no_autowrap, getBool, NULL, NULL, NULL},
|
&wPreferences.no_autowrap, getBool, NULL, NULL, NULL},
|
||||||
|
{"WindowSnapping", "NO", NULL,
|
||||||
|
&wPreferences.window_snapping, getBool, NULL, NULL, NULL},
|
||||||
{"HighlightActiveApp", "YES", NULL,
|
{"HighlightActiveApp", "YES", NULL,
|
||||||
&wPreferences.highlight_active_app, getBool, NULL, NULL, NULL},
|
&wPreferences.highlight_active_app, getBool, NULL, NULL, NULL},
|
||||||
{"AutoArrangeIcons", "NO", NULL,
|
{"AutoArrangeIcons", "NO", NULL,
|
||||||
|
|||||||
@@ -588,6 +588,8 @@ typedef struct {
|
|||||||
int calcX, calcY; /* calculated position of window */
|
int calcX, calcY; /* calculated position of window */
|
||||||
int omouseX, omouseY; /* old mouse position */
|
int omouseX, omouseY; /* old mouse position */
|
||||||
int mouseX, mouseY; /* last known position of the pointer */
|
int mouseX, mouseY; /* last known position of the pointer */
|
||||||
|
|
||||||
|
enum {SNAP_NONE, SNAP_LEFT, SNAP_RIGHT} snap;
|
||||||
} MoveData;
|
} MoveData;
|
||||||
|
|
||||||
#define WTOP(w) (w)->frame_y
|
#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->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->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)
|
static Bool checkWorkspaceChange(WWindow * wwin, MoveData * data, Bool opaqueMove)
|
||||||
@@ -1642,12 +1646,48 @@ int wMouseMoveWindow(WWindow * wwin, XEvent * ev)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MotionNotify:
|
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 (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,
|
updateWindowPosition(wwin, &moveData,
|
||||||
scr->selected_windows == NULL
|
scr->selected_windows == NULL
|
||||||
&& wPreferences.edge_resistance > 0,
|
&& wPreferences.edge_resistance > 0,
|
||||||
opaqueMove, event.xmotion.x_root, event.xmotion.y_root);
|
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) {
|
if (!warped && !wPreferences.no_autowrap) {
|
||||||
int oldWorkspace = w_global.workspace.current;
|
int oldWorkspace = w_global.workspace.current;
|
||||||
|
|
||||||
@@ -1703,6 +1743,7 @@ int wMouseMoveWindow(WWindow * wwin, XEvent * ev)
|
|||||||
showPosition(wwin, moveData.realX, moveData.realY);
|
showPosition(wwin, moveData.realX, moveData.realY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ButtonPress:
|
case ButtonPress:
|
||||||
@@ -1712,7 +1753,28 @@ int wMouseMoveWindow(WWindow * wwin, XEvent * ev)
|
|||||||
if (event.xbutton.button != ev->xbutton.button)
|
if (event.xbutton.button != ev->xbutton.button)
|
||||||
break;
|
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;
|
XEvent e;
|
||||||
if (!opaqueMove) {
|
if (!opaqueMove) {
|
||||||
drawFrames(wwin, scr->selected_windows,
|
drawFrames(wwin, scr->selected_windows,
|
||||||
|
|||||||
Reference in New Issue
Block a user