From: Daniel Déchelotte <[email protected]>
Add WrapAppiconsInDock option to control that behaviour (default: YES)
---
src/WindowMaker.h | 4 +-
src/defaults.c | 9 +++
src/dock.c | 210 +++++++++++++++++++++++++++++++++++------------------
3 files changed, 150 insertions(+), 73 deletions(-)
diff --git a/src/WindowMaker.h b/src/WindowMaker.h
index c37c34a..7ec96d1 100644
--- a/src/WindowMaker.h
+++ b/src/WindowMaker.h
@@ -443,7 +443,9 @@ typedef struct WPreferences {
struct {
unsigned int nodock:1; /* don't display the dock */
unsigned int noclip:1; /* don't display the clip */
- unsigned int nodrawer:1; /* don't use drawers */
+ unsigned int nodrawer:1; /* don't use drawers */
+ unsigned int wrap_appicons_in_dock:1; /* Whether to wrap appicons when
Dock is moved up and down */
+
unsigned int noupdates:1; /* don't require ~/GNUstep (-static) */
unsigned int noautolaunch:1; /* don't autolaunch apps */
unsigned int norestore:1; /* don't restore session */
diff --git a/src/defaults.c b/src/defaults.c
index c2fceb6..3543f82 100644
--- a/src/defaults.c
+++ b/src/defaults.c
@@ -113,6 +113,7 @@ static int getPropList();
static int setJustify();
static int setClearance();
static int setIfDockPresent();
+static int setWrapAppiconsInDock();
static int setStickyIcons();
static int setWidgetColor();
static int setIconTile();
@@ -404,6 +405,8 @@ WDefaultEntry optionList[] = {
&wPreferences.clip_auto_expand_delay, getInt, NULL, NULL, NULL},
{"ClipAutocollapseDelay", "1000", NULL,
&wPreferences.clip_auto_collapse_delay, getInt, NULL, NULL, NULL},
+ {"WrapAppiconsInDock", "YES", NULL,
+ NULL, getBool, setWrapAppiconsInDock, NULL, NULL},
{"AlignSubmenus", "NO", NULL,
&wPreferences.align_menus, getBool, NULL, NULL, NULL},
{"ViKeyMenus", "NO", NULL,
@@ -2346,6 +2349,12 @@ static int setIfDockPresent(WScreen * scr, WDefaultEntry
* entry, char *flag, lo
return 0;
}
+static int setWrapAppiconsInDock(WScreen *scr, WDefaultEntry *entry, char
*flag, void *foo)
+{
+ wPreferences.flags.wrap_appicons_in_dock = *flag;
+ return 0;
+}
+
static int setStickyIcons(WScreen * scr, WDefaultEntry * entry, void *bar,
void *foo)
{
if (scr->workspaces) {
diff --git a/src/dock.c b/src/dock.c
index ef382e2..ebee9c3 100644
--- a/src/dock.c
+++ b/src/dock.c
@@ -2463,22 +2463,22 @@ Bool wDockSnapIcon(WDock *dock, WAppIcon *icon, int
req_x, int req_y, int *ret_x
if (!onScreen(scr, dx + ex_x * ICON_SIZE, dy + ex_y * ICON_SIZE))
return False;
- switch (dock->type) {
- case WM_DOCK:
- /* We can return False right away if
- * - we do not come from this dock (which is a WM_DOCK),
- * - we are not right over it, and
- * - we are not the main tile of a drawer.
- * In the latter case, we are called from handleDockMove. */
+ switch (dock->type) {
+ case WM_DOCK:
+ /* We can return False right away if
+ * - we do not come from this dock (which is a WM_DOCK),
+ * - we are not right over it, and
+ * - we are not the main tile of a drawer.
+ * In the latter case, we are called from handleDockMove. */
if (icon->dock != dock && ex_x != 0 &&
- !(icon->dock && icon->dock->type == WM_DRAWER && icon ==
icon->dock->icon_array[0]))
+ !(icon->dock && icon->dock->type == WM_DRAWER && icon
== icon->dock->icon_array[0]))
return False;
if (!redocking && ex_x != 0)
- return False;
+ return False;
- if (getDrawer(scr, ex_y)) /* Return false so that the drawer gets it.
*/
- return False;
+ if (getDrawer(scr, ex_y)) /* Return false so that the drawer
gets it. */
+ return False;
aicon = NULL;
for (i = 0; i < dock->max_icons; i++) {
@@ -2495,7 +2495,7 @@ Bool wDockSnapIcon(WDock *dock, WAppIcon *icon, int
req_x, int req_y, int *ret_x
/* Possible cases when redocking:
*
* icon dragged out of range of any slot -> false
- * icon dragged on a drawer -> false (to open the drawer)
+ * icon dragged on a drawer -> false (to open the
drawer)
* icon dragged to range of free slot
* icon dragged to range of same slot
* icon dragged to range of different icon
@@ -2533,16 +2533,16 @@ Bool wDockSnapIcon(WDock *dock, WAppIcon *icon, int
req_x, int req_y, int *ret_x
break;
}
}
- /* slot is used by a drawer */
- done = done && !getDrawer(scr, closest);
+ /* slot is used by a drawer */
+ done = done && !getDrawer(scr, closest);
}
else // !onScreen
done = 0;
sig = -sig;
}
if (done &&
- ((ex_y >= closest && ex_y - closest <
DOCK_DETTACH_THRESHOLD + 1)
- || (ex_y < closest && closest - ex_y <=
DOCK_DETTACH_THRESHOLD + 1))) {
+ ((ex_y >= closest && ex_y - closest <
DOCK_DETTACH_THRESHOLD + 1)
+ || (ex_y < closest && closest - ex_y <=
DOCK_DETTACH_THRESHOLD + 1))) {
*ret_x = 0;
*ret_y = closest;
return True;
@@ -2606,45 +2606,45 @@ Bool wDockSnapIcon(WDock *dock, WAppIcon *icon, int
req_x, int req_y, int *ret_x
}
case WM_DRAWER:
{
- WAppIcon *aicons_to_shift[ dock->icon_count ];
- int index_of_hole, j;
-
- if (ex_y != 0 ||
- abs(ex_x) - dock->icon_count > DOCK_DETTACH_THRESHOLD ||
- (ex_x < 0 && !dock->on_right_side) ||
- (ex_x > 0 && dock->on_right_side)) {
- return False;
- }
-
- if (ex_x == 0)
- ex_x = (dock->on_right_side ? -1 : 1);
-
- /* "Reduce" ex_x but keep its sign */
- if (redocking) {
- if (abs(ex_x) > dock->icon_count - 1) /* minus 1: do not take
icon_array[0] into account */
- ex_x = ex_x * (dock->icon_count - 1) / abs(ex_x); /* don't use
*= ! */
- } else {
- if (abs(ex_x) > dock->icon_count)
- ex_x = ex_x * dock->icon_count / abs(ex_x);
- }
- index_of_hole = indexOfHole(dock, icon, redocking);
-
- /* Find the appicons between where icon was (index_of_hole) and where
- * it wants to be (ex_x) and slide them. */
- j = 0;
- for (i = 1; i < dock->max_icons; i++) {
- if ((aicon = dock->icon_array[ i ]) && aicon != icon &&
- ((ex_x <= aicon->xindex && aicon->xindex < index_of_hole) ||
- (index_of_hole < aicon->xindex && aicon->xindex <= ex_x)))
- aicons_to_shift[ j++ ] = aicon;
- }
- assert(j == abs(ex_x - index_of_hole));
-
- wSlideAppicons(aicons_to_shift, j, (index_of_hole < ex_x));
-
- *ret_x = ex_x;
- *ret_y = ex_y;
- return True;
+ WAppIcon *aicons_to_shift[ dock->icon_count ];
+ int index_of_hole, j;
+
+ if (ex_y != 0 ||
+ abs(ex_x) - dock->icon_count > DOCK_DETTACH_THRESHOLD ||
+ (ex_x < 0 && !dock->on_right_side) ||
+ (ex_x > 0 && dock->on_right_side)) {
+ return False;
+ }
+
+ if (ex_x == 0)
+ ex_x = (dock->on_right_side ? -1 : 1);
+
+ /* "Reduce" ex_x but keep its sign */
+ if (redocking) {
+ if (abs(ex_x) > dock->icon_count - 1) /* minus 1: do
not take icon_array[0] into account */
+ ex_x = ex_x * (dock->icon_count - 1) /
abs(ex_x); /* don't use *= ! */
+ } else {
+ if (abs(ex_x) > dock->icon_count)
+ ex_x = ex_x * dock->icon_count / abs(ex_x);
+ }
+ index_of_hole = indexOfHole(dock, icon, redocking);
+
+ /* Find the appicons between where icon was (index_of_hole) and
where
+ * it wants to be (ex_x) and slide them. */
+ j = 0;
+ for (i = 1; i < dock->max_icons; i++) {
+ if ((aicon = dock->icon_array[ i ]) && aicon != icon &&
+ ((ex_x <= aicon->xindex && aicon->xindex <
index_of_hole) ||
+ (index_of_hole < aicon->xindex &&
aicon->xindex <= ex_x)))
+ aicons_to_shift[ j++ ] = aicon;
+ }
+ assert(j == abs(ex_x - index_of_hole));
+
+ wSlideAppicons(aicons_to_shift, j, (index_of_hole < ex_x));
+
+ *ret_x = ex_x;
+ *ret_y = ex_y;
+ return True;
}
}
return False;
@@ -3126,9 +3126,9 @@ void wDockRaise(WDock *dock)
wRaiseFrame(dock->icon_array[i]->icon->core);
}
if (dock->type == WM_DOCK) {
- for (dc = dock->screen_ptr->drawers; dc != NULL; dc = dc->next)
- wDockRaise(dc->adrawer);
- }
+ for (dc = dock->screen_ptr->drawers; dc != NULL; dc = dc->next)
+ wDockRaise(dc->adrawer);
+ }
}
void wDockRaiseLower(WDock *dock)
@@ -3611,10 +3611,12 @@ static void handleDockMove(WDock *dock, WAppIcon
*aicon, XEvent *event)
WScreen *scr = dock->screen_ptr;
int ofs_x = event->xbutton.x, ofs_y = event->xbutton.y;
WIcon *icon = aicon->icon;
+ WAppIcon *tmpaicon;
+ WDrawerChain *dc;
int x = aicon->x_pos, y = aicon->y_pos;;
int shad_x = x, shad_y = y;
XEvent ev;
- int grabbed = 0, done, previously_on_right, now_on_right,
previous_x_pos;
+ int grabbed = 0, done, previously_on_right, now_on_right,
previous_x_pos, i;
Pixmap ghost = None;
int superfluous = wPreferences.superfluous; /* we catch it to avoid
problems */
@@ -3698,6 +3700,57 @@ static void handleDockMove(WDock *dock, WAppIcon *aicon,
XEvent *event)
// Also perform the vertical move
wScreenKeepInside(scr, &x, &y, ICON_SIZE,
ICON_SIZE);
moveDock(dock, dock->x_pos, y);
+ if (wPreferences.flags.wrap_appicons_in_dock)
+ {
+ for (i = 0; i < dock->max_icons; i++) {
+ int new_y, new_index, j, ok;
+ if ((tmpaicon =
dock->icon_array[i]) == NULL)
+ continue;
+ if (onScreen(scr,
tmpaicon->x_pos, tmpaicon->y_pos))
+ continue;
+ new_y = (tmpaicon->y_pos +
ICON_SIZE * dock->max_icons) % (ICON_SIZE * dock->max_icons);
+ new_index = (new_y -
dock->y_pos) / ICON_SIZE;
+ if (!onScreen(scr,
tmpaicon->x_pos, new_y))
+ continue;
+ ok = 1;
+ for (j = 0; j <
dock->max_icons; j++)
+ {
+ if (dock->icon_array[j]
!= NULL &&
+
dock->icon_array[j]->yindex == new_index)
+ {
+ ok = 0;
+ break;
+ }
+ }
+ if (!ok || getDrawer(scr,
new_index) != NULL)
+ continue;
+ wDockReattachIcon(dock,
tmpaicon, tmpaicon->xindex, new_index);
+ }
+ for (dc = scr->drawers; dc != NULL; dc
= dc->next)
+ {
+ int new_y, new_index, j, ok;
+ tmpaicon =
dc->adrawer->icon_array[0];
+ if (onScreen(scr,
tmpaicon->x_pos, tmpaicon->y_pos))
+ continue;
+ new_y = (tmpaicon->y_pos +
ICON_SIZE * dock->max_icons) % (ICON_SIZE * dock->max_icons);
+ new_index = (new_y -
dock->y_pos) / ICON_SIZE;
+ if (!onScreen(scr,
tmpaicon->x_pos, new_y))
+ continue;
+ ok = 1;
+ for (j = 0; j <
dock->max_icons; j++)
+ {
+ if (dock->icon_array[j]
!= NULL &&
+
dock->icon_array[j]->yindex == new_index)
+ {
+ ok = 0;
+ break;
+ }
+ }
+ if (!ok || getDrawer(scr,
new_index) != NULL)
+ continue;
+ moveDock(dc->adrawer,
tmpaicon->x_pos, new_y);
+ }
+ }
break;
case WM_DRAWER:
{
@@ -3726,14 +3779,12 @@ static void handleDockMove(WDock *dock, WAppIcon
*aicon, XEvent *event)
break;
XUngrabPointer(dpy, CurrentTime);
if (dock->type == WM_DRAWER) {
- int i;
Window *wins[dock->icon_count];
- WAppIcon *aicon;
for (i = 0; i < dock->max_icons; i++) {
- if ((aicon = dock->icon_array[i]) ==
NULL)
+ if ((tmpaicon = dock->icon_array[i]) ==
NULL)
continue;
- wins[ aicon->xindex +
(dock->on_right_side ? dock->icon_count - 1 : 0) ] = &aicon->icon->core->window;
+ wins[ tmpaicon->xindex +
(dock->on_right_side ? dock->icon_count - 1 : 0) ] =
&tmpaicon->icon->core->window;
}
SlideWindows(wins, dock->icon_count,
(dock->on_right_side ? x -
(dock->icon_count - 1) * ICON_SIZE : x),
@@ -4226,30 +4277,45 @@ static void drawerIconExpose(WObjDescriptor *desc,
XEvent *event)
static int addADrawer(WScreen *scr)
{
- int i, y;
+ int i, y, sig, found_y;
WDock *drawer, *dock = scr->dock;
WDrawerChain *dc;
- char can_be_here[dock->max_icons];
+ char can_be_here[2 * dock->max_icons - 1];
if (dock->icon_count + scr->drawer_count >= dock->max_icons)
return -1;
- for (y = 0; y < dock->max_icons; y++) {
- can_be_here[y] = True;
+ for (y = -dock->max_icons + 1; y < dock->max_icons; y++) {
+ can_be_here[y + dock->max_icons - 1] = True;
}
for (i = 0; i < dock->max_icons; i++) {
if (dock->icon_array[i] != NULL)
- can_be_here[dock->icon_array[i]->yindex] = False;
+ can_be_here[dock->icon_array[i]->yindex +
dock->max_icons - 1] = False;
}
for (dc = scr->drawers; dc != NULL; dc = dc->next) {
y = (int) ((dc->adrawer->y_pos - dock->y_pos) / ICON_SIZE);
- can_be_here[y] = False;
+ can_be_here[y + dock->max_icons - 1] = False;
}
- for (y = 0; y < dock->max_icons; y++) {
- if (can_be_here[y])
- break;
+ found_y = False;
+ for (sig = 1; !found_y && sig > -2; sig -= 2) // 1, then -1
+ {
+ for (y = sig; sig * y < dock->max_icons; y += sig)
+ {
+ if (can_be_here[y + dock->max_icons - 1] &&
+ onScreen(scr, dock->x_pos, dock->y_pos + y *
ICON_SIZE))
+ {
+ found_y = True;
+ break;
+ }
+ }
}
+
+ if (!found_y)
+ /* This can happen even when dock->icon_count +
scr->drawer_count
+ * < dock->max_icons when the dock is not aligned on an
+ * ICON_SIZE multiple, as some space is lost above and under it
*/
+ return -1;
drawer = wDockCreate(scr, WM_DRAWER, NULL);
drawer->lowered = scr->dock->lowered;
--
1.7.10.4
--
To unsubscribe, send mail to [email protected].