From 824edac371801650dd8176e846ef7d895d913e00 Mon Sep 17 00:00:00 2001 From: id Date: Wed, 14 Jul 1999 14:42:29 +0000 Subject: [PATCH] Edge attraction. --- WPrefs.app/WindowHandling.c | 29 ++++- src/WindowMaker.h | 1 + src/defaults.c | 3 + src/moveres.c | 295 ++++++++++++++++++++++++++++++-------------- 4 files changed, 233 insertions(+), 95 deletions(-) diff --git a/WPrefs.app/WindowHandling.c b/WPrefs.app/WindowHandling.c index 6142f9ef..1c047620 100644 --- a/WPrefs.app/WindowHandling.c +++ b/WPrefs.app/WindowHandling.c @@ -47,6 +47,8 @@ typedef struct _Panel { WMFrame *resF; WMSlider *resS; WMLabel *resL; + WMButton *resaB; + WMButton *resrB; WMFrame *maxiF; WMButton *miconB; @@ -179,6 +181,11 @@ showData(_Panel *panel) WMSetButtonSelected(panel->miconB, GetBoolForKey("NoWindowOverIcons")); WMSetButtonSelected(panel->mdockB, GetBoolForKey("NoWindowOverDock")); + + if (GetBoolForKey("Attraction")) + WMPerformButtonClick(panel->resrB); + else + WMPerformButtonClick(panel->resaB); } @@ -199,6 +206,7 @@ storeData(_Panel *panel) arr = PLMakeArrayFromElements(PLMakeString(x), PLMakeString(y), NULL); SetObjectForKey(arr, "WindowPlaceOrigin"); SetIntegerForKey(WMGetSliderValue(panel->resS), "EdgeResistance"); + SetBoolForKey(WMGetButtonSelected(panel->resrB), "Attraction"); PLRelease(arr); } @@ -366,15 +374,28 @@ createPanel(Panel *p) "of the screen."), WMWidgetView(panel->resF)); panel->resS = WMCreateSlider(panel->resF); - WMResizeWidget(panel->resS, 200, 15); - WMMoveWidget(panel->resS, 20, 20); + WMResizeWidget(panel->resS, 80, 15); + WMMoveWidget(panel->resS, 10, 20); WMSetSliderMinValue(panel->resS, 0); - WMSetSliderMaxValue(panel->resS, 200); + WMSetSliderMaxValue(panel->resS, 80); WMSetSliderAction(panel->resS, resistanceCallback, panel); panel->resL = WMCreateLabel(panel->resF); WMResizeWidget(panel->resL, 30, 15); - WMMoveWidget(panel->resL, 230, 20); + WMMoveWidget(panel->resL, 95, 20); + + panel->resaB = WMCreateRadioButton(panel->resF); + WMMoveWidget(panel->resaB, 130, 12); + WMResizeWidget(panel->resaB, 70, 30); + WMSetButtonText(panel->resaB, _("Resist")); + + panel->resrB = WMCreateRadioButton(panel->resF); + WMMoveWidget(panel->resrB, 200, 12); + WMResizeWidget(panel->resrB, 65, 30); + WMSetButtonText(panel->resrB, _("Attract")); + WMGroupButtons(panel->resrB, panel->resaB); + + WMMapSubwidgets(panel->resF); diff --git a/src/WindowMaker.h b/src/WindowMaker.h index e38677d7..bc90db6b 100644 --- a/src/WindowMaker.h +++ b/src/WindowMaker.h @@ -410,6 +410,7 @@ typedef struct WPreferences { char shade_speed; int edge_resistance; + char attract; struct { unsigned int nodock:1; /* don't display the dock */ diff --git a/src/defaults.c b/src/defaults.c index 030c0927..73b4936a 100644 --- a/src/defaults.c +++ b/src/defaults.c @@ -492,6 +492,9 @@ WDefaultEntry optionList[] = { {"EdgeResistance", "30", NULL, &wPreferences.edge_resistance,getInt, NULL }, + {"Attraction", "NO", NULL, + &wPreferences.attract, getBool, NULL + }, {"DisableBlinking", "NO", NULL, &wPreferences.dont_blink, getBool, NULL }, diff --git a/src/moveres.c b/src/moveres.c index eacc0a97..63f483ed 100644 --- a/src/moveres.c +++ b/src/moveres.c @@ -926,6 +926,7 @@ updateWindowPosition(WWindow *wwin, MoveData *data, Bool doResistance, int newX, newY; /* actual new window position */ Bool hresist, vresist; Bool updateIndex; + Bool attract; hresist = False; vresist = False; @@ -950,105 +951,213 @@ updateWindowPosition(WWindow *wwin, MoveData *data, Bool doResistance, newY = data->realY; if (doResistance) { - int edge; + int l_edge, r_edge; + int edge_l, edge_r; + int t_edge, b_edge; + int edge_t, edge_b; int resist; WWindow *rwin; + WWindow *rrwin; - resist = wPreferences.edge_resistance; + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + attract = wPreferences.attract; /* horizontal movement: check horizontal edge resistances */ - if (dx < 0) { + if (dx || dy) { + int i; /* window is the leftmost window: check against screen edge */ - edge = scr->totalUsableArea.x1; + l_edge = scr->totalUsableArea.x1; + r_edge = scr->totalUsableArea.x2 + resist; + edge_l = scr->totalUsableArea.x1 - resist; + edge_r = scr->totalUsableArea.x2; + + /* 1 */ + if ((data->rightIndex >= 0) && (data->rightIndex <= data->count)) { + WWindow *looprw; + + for (i = data->rightIndex - 1; i >= 0; i--) { + looprw = data->rightList[i]; + if (!(data->realY > WBOTTOM(looprw) + || (data->realY + data->winHeight) < WTOP(looprw))) { + if (attract || (data->realX < (WRIGHT(looprw) + 2)) && dx < 0) { + l_edge = WRIGHT(looprw) + 1; + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + } + break; + } + } - /* check position of nearest window to the left */ - if (data->rightIndex > 0) { - /* there is some window at the left: check if it will block - * the window */ - rwin = data->rightList[data->rightIndex - 1]; + if (attract) { + for (i = data->rightIndex; i < data->count; i++) { + looprw = data->rightList[i]; + if(!(data->realY > WBOTTOM(looprw) + || (data->realY + data->winHeight) < WTOP(looprw))) { + r_edge = WRIGHT(looprw) + 1; + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + break; + } + } + } + } - if (data->realY > WBOTTOM(rwin) - || (data->realY + data->winHeight) < WTOP(rwin)) { - resist = 0; - } else { - edge = WRIGHT(rwin) + 1; - resist = WIN_RESISTANCE(wPreferences.edge_resistance); - } - } - if (resist > 0 && winL >= edge - resist && winL <= edge) { - newX = edge; - hresist = True; - } - } else if (dx > 0) { - /* window is the rightmost window: check against screen edge */ - edge = scr->totalUsableArea.x2; - - /* check position of nearest window to the right */ - if (data->leftIndex > 0) { - /* there is some window at the right: check if it will block - * the window */ - rwin = data->leftList[data->leftIndex - 1]; - - if (data->realY > WBOTTOM(rwin) - || (data->realY + data->winHeight) < WTOP(rwin)) { - resist = 0; - } else { - edge = WLEFT(rwin); - resist = WIN_RESISTANCE(wPreferences.edge_resistance); - } - } - if (resist > 0 && winR <= edge + resist && winR >= edge) { - newX = edge - data->winWidth; - hresist = True; - } - } + if ((data->leftIndex >= 0) && (data->leftIndex <= data->count)) { + WWindow *looprw; + + for (i = data->leftIndex - 1; i >= 0; i--) { + looprw = data->leftList[i]; + if (!(data->realY > WBOTTOM(looprw) + || (data->realY + data->winHeight) < WTOP(looprw))) { + if (attract || ((data->realX + data->winWidth) > (WLEFT(looprw) - 1)) && dx > 0) { + edge_r = WLEFT(looprw); + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + } + break; + } + } - resist = wPreferences.edge_resistance; - /* vertical movement: check vertical edge resistances */ - if (dy < 0) { - /* window is the topmost window: check against screen edge */ - edge = scr->totalUsableArea.y1; - - /* check position of nearest window to the top */ - if (data->bottomIndex > 0) { - /* there is some window at the top: check if it will block - * the window */ - rwin = data->bottomList[data->bottomIndex - 1]; - - if (data->realX > WRIGHT(rwin) - || (data->realX + data->winWidth) < WLEFT(rwin)) { - resist = 0; - } else { - edge = WBOTTOM(rwin) + 1; - resist = WIN_RESISTANCE(wPreferences.edge_resistance); - } - } - if (resist > 0 && winT >= edge - resist && winT <= edge) { - newY = edge; - vresist = True; - } - } else if (dy > 0) { - /* window is the bottommost window: check against screen edge */ - edge = scr->totalUsableArea.y2; - - /* check position of nearest window to the bottom */ - if (data->topIndex > 0) { - /* there is some window at the bottom: check if it will block - * the window */ - rwin = data->topList[data->topIndex - 1]; - - if (data->realX > WRIGHT(rwin) - || (data->realX + data->winWidth) < WLEFT(rwin)) { - resist = 0; - } else { - edge = WTOP(rwin); - resist = WIN_RESISTANCE(wPreferences.edge_resistance); - } - } - if (resist > 0 && winB <= edge + resist && winB >= edge) { - newY = edge - data->winHeight; - vresist = True; - } + if (attract) + for (i = data->leftIndex; i < data->count; i++) { + looprw = data->leftList[i]; + if(!(data->realY > WBOTTOM(looprw) + || (data->realY + data->winHeight) < WTOP(looprw))) { + edge_l = WLEFT(looprw); + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + break; + } + } + } + + /* + printf("%d %d\n",winL,winR); + printf("l_ %d r_ %d _l %d _r %d\n",l_edge,r_edge,edge_l,edge_r); + */ + + if ((winL - l_edge) < (r_edge - winL)) { + if (resist > 0) { + if ((attract && winL <= l_edge + resist && winL >= l_edge - resist) + || (dx < 0 && winL <= l_edge && winL >= l_edge - resist)) { + newX = l_edge; + hresist = True; + } + } + } + else { + if (resist > 0 && attract && winL >= r_edge - resist && winL <= r_edge + resist) { + newX = r_edge; + hresist = True; + } + } + + if ((winR - edge_l) < (edge_r - winR)) { + if (resist > 0 && attract && winR <= edge_l + resist && winR >= edge_l - resist) { + newX = edge_l - data->winWidth; + hresist = True; + } + } + else { + if (resist > 0) { + if ((attract && winR >= edge_r - resist && winR <= edge_r + resist) + || (dx > 0 && winR >= edge_r && winR <= edge_r + resist)) { + newX = edge_r - data->winWidth; + hresist = True; + } + } + } + + /* VeRT */ + t_edge = scr->totalUsableArea.y1; + b_edge = scr->totalUsableArea.y2 + resist; + edge_t = scr->totalUsableArea.y1 - resist; + edge_b = scr->totalUsableArea.y2; + + if ((data->bottomIndex >= 0) && (data->bottomIndex <= data->count)) { + WWindow *looprw; + + for (i = data->bottomIndex - 1; i >= 0; i--) { + looprw = data->bottomList[i]; + if (!(data->realX > WRIGHT(looprw) + || (data->realX + data->winWidth) < WLEFT(looprw))) { + if (attract || (data->realY < (WBOTTOM(looprw) + 2)) && dy < 0) { + t_edge = WBOTTOM(looprw) + 1; + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + } + break; + } + } + + if (attract) { + for (i = data->bottomIndex; i < data->count; i++) { + looprw = data->bottomList[i]; + if(!(data->realX > WRIGHT(looprw) + || (data->realX + data->winWidth) < WLEFT(looprw))) { + b_edge = WBOTTOM(looprw) + 1; + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + break; + } + } + } + } + + if ((data->topIndex >= 0) && (data->topIndex <= data->count)) { + WWindow *looprw; + + for (i = data->topIndex - 1; i >= 0; i--) { + looprw = data->topList[i]; + if (!(data->realX > WRIGHT(looprw) + || (data->realX + data->winWidth) < WLEFT(looprw))) { + if (attract || ((data->realY + data->winHeight) > (WTOP(looprw) - 1)) && dy > 0) { + edge_b = WTOP(looprw); + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + } + break; + } + } + + if (attract) + for (i = data->topIndex; i < data->count; i++) { + looprw = data->topList[i]; + if(!(data->realX > WRIGHT(looprw) + || (data->realX + data->winWidth) < WLEFT(looprw))) { + edge_t = WTOP(looprw); + resist = WIN_RESISTANCE(wPreferences.edge_resistance); + break; + } + } + } + + if ((winT - t_edge) < (b_edge - winT)) { + if (resist > 0) { + if ((attract && winT <= t_edge + resist && winT >= t_edge - resist) + || (dy < 0 && winT <= t_edge && winT >= t_edge - resist)) { + newY = t_edge; + vresist = True; + } + } + } + else { + if (resist > 0 && attract && winT >= b_edge - resist && winT <= b_edge + resist) { + newY = b_edge; + vresist = True; + } + } + + if ((winB - edge_t) < (edge_b - winB)) { + if (resist > 0 && attract && winB <= edge_t + resist && winB >= edge_t - resist) { + newY = edge_t - data->winHeight; + vresist = True; + } + } + else { + if (resist > 0) { + if ((attract && winB >= edge_b - resist && winB <= edge_b + resist) + || (dy > 0 && winB >= edge_b && winB <= edge_b + resist)) { + newY = edge_b - data->winHeight; + vresist = True; + } + } + } } + /* END VeRT */ + } /* update window position */ @@ -1443,6 +1552,7 @@ wMouseMoveWindow(WWindow *wwin, XEvent *ev) rimg = InitGhostWindowMove(scr); #endif + if (wPreferences.opaque_move && !wPreferences.use_saveunders) { XSetWindowAttributes attr; @@ -1451,6 +1561,7 @@ wMouseMoveWindow(WWindow *wwin, XEvent *ev) CWSaveUnder, &attr); } + initMoveData(wwin, &moveData); moveData.mouseX = ev->xmotion.x_root; @@ -1469,7 +1580,7 @@ wMouseMoveWindow(WWindow *wwin, XEvent *ev) if (warped) { int junk; Window junkw; - + /* XWarpPointer() doesn't seem to generate Motion events, so we've got to simulate them */ XQueryPointer(dpy, root, &junkw, &junkw, &event.xmotion.x_root, @@ -1649,9 +1760,11 @@ wMouseMoveWindow(WWindow *wwin, XEvent *ev) if (wPreferences.opaque_move && !wPreferences.use_saveunders) { XSetWindowAttributes attr; + attr.save_under = False; XChangeWindowAttributes(dpy, wwin->frame->core->window, CWSaveUnder, &attr); + } freeMoveData(&moveData); -- 2.11.4.GIT