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

Merging appicon.c:appIconMouseDown and dock.c:handleIconMove into appicon.c:wHandleAppIconMove

Behaves essentially the same, only a bit more consistently.
Known differences:
1. An AppIcon will now always end up undocked if moved while Mod1 is pressed.
2. Moving a docked AppIcon with Mod1 pressed (undocking it) used to auto-expand the clip,
   as clip expansion happened first, while looking for a snapping position,
   and the test on Mod1 being pressed happened only later
This commit is contained in:
Daniel Déchelotte
2013-04-12 01:42:38 +02:00
committed by Carlos R. Mafra
parent 8b6ff01d39
commit 9fae35fbc4
4 changed files with 235 additions and 346 deletions

View File

@@ -63,6 +63,7 @@ extern WDDomain *WDWindowAttributes;
extern XContext wWinContext; extern XContext wWinContext;
#define MOD_MASK wPreferences.modifier_mask #define MOD_MASK wPreferences.modifier_mask
#define ICON_SIZE wPreferences.icon_size
void appIconMouseDown(WObjDescriptor * desc, XEvent * event); void appIconMouseDown(WObjDescriptor * desc, XEvent * event);
static void iconDblClick(WObjDescriptor * desc, XEvent * event); static void iconDblClick(WObjDescriptor * desc, XEvent * event);
@@ -667,24 +668,8 @@ static void iconDblClick(WObjDescriptor *desc, XEvent *event)
void appIconMouseDown(WObjDescriptor * desc, XEvent * event) void appIconMouseDown(WObjDescriptor * desc, XEvent * event)
{ {
WAppIcon *aicon = desc->parent; WAppIcon *aicon = desc->parent;
WIcon *icon = aicon->icon; WScreen *scr = aicon->icon->core->screen_ptr;
XEvent ev; Bool hasMoved;
int x = aicon->x_pos, y = aicon->y_pos;
int dx = event->xbutton.x, dy = event->xbutton.y;
int grabbed = 0;
int done = 0;
int superfluous = wPreferences.superfluous; /* we catch it to avoid problems */
WScreen *scr = icon->core->screen_ptr;
WWorkspace *workspace = scr->workspaces[scr->current_workspace];
int shad_x = 0, shad_y = 0, docking = 0, dockable, collapsed = 0;
int ix, iy;
int clickButton = event->xbutton.button;
Pixmap ghost = None;
Window wins[2];
Bool movingSingle = False;
int oldX = x;
int oldY = y;
Bool hasMoved = False;
if (aicon->editing || WCHECK_STATE(WSTATE_MODAL)) if (aicon->editing || WCHECK_STATE(WSTATE_MODAL))
return; return;
@@ -729,24 +714,92 @@ void appIconMouseDown(WObjDescriptor * desc, XEvent * event)
return; return;
} }
if (event->xbutton.state & MOD_MASK) hasMoved = wHandleAppIconMove(aicon, event);
wLowerFrame(icon->core); if (wPreferences.single_click && !hasMoved && aicon->dock != NULL)
else {
iconDblClick(desc, event);
}
}
Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
{
WDock *originalDock = aicon->dock; /* can be NULL */
WDock *lastDock = originalDock;
WDock *allDocks[2]; /* clip and dock (order to be determined at runtime) */
Bool done = False, dockable, ondock;
Bool grabbed = False;
Bool collapsed = False; /* Stores the collapsed state of lastDock, before the moving appicon entered it */
int superfluous = wPreferences.superfluous; /* we cache it to avoid problems */
int omnipresent = aicon->omnipresent; /* this must be cached */
Bool showed_all_clips = False;
WIcon *icon = aicon->icon;
WScreen *scr = icon->core->screen_ptr;
int clickButton = event->xbutton.button;
Pixmap ghost = None;
Window wins[2]; /* Managing shadow window */
XEvent ev;
int x = aicon->x_pos, y = aicon->y_pos;
int ofs_x = event->xbutton.x, ofs_y = event->xbutton.y;
int shad_x = x, shad_y = y;
int ix = aicon->xindex, iy = aicon->yindex;
int i;
int oldX = x;
int oldY = y;
Bool hasMoved = False;
if (wPreferences.flags.noupdates && originalDock != NULL)
return False;
if (!(event->xbutton.state & MOD_MASK))
wRaiseFrame(icon->core); wRaiseFrame(icon->core);
else {
/* If Mod is pressed for an docked appicon, assume it is to undock it,
* so don't lower it */
if (originalDock == NULL)
wLowerFrame(icon->core);
}
if (XGrabPointer(dpy, icon->core->window, True, ButtonMotionMask if (XGrabPointer(dpy, icon->core->window, True, ButtonMotionMask
| ButtonReleaseMask | ButtonPressMask, GrabModeAsync, | ButtonReleaseMask | ButtonPressMask, GrabModeAsync,
GrabModeAsync, None, None, CurrentTime) != GrabSuccess) GrabModeAsync, None, None, CurrentTime) != GrabSuccess) {
wwarning("pointer grab failed for appicon move"); wwarning("Pointer grab failed in wHandleAppIconMove");
}
if (originalDock != NULL) {
dockable = True;
ondock = True;
}
else {
ondock = False;
if (wPreferences.flags.nodock && wPreferences.flags.noclip) if (wPreferences.flags.nodock && wPreferences.flags.noclip)
dockable = 0; dockable = 0;
else else
dockable = canBeDocked(icon->owner); dockable = canBeDocked(icon->owner);
}
/* We try the various docks in that order:
* - First, the dock the appicon comes from, if any
* - Then, the "dock" (WM_DOCK)
* - Finally, the clip
*/
i = 0;
if (originalDock != NULL)
allDocks[ i++ ] = originalDock;
if (!wPreferences.flags.nodock && scr->dock != originalDock)
allDocks[ i++ ] = scr->dock;
if (!wPreferences.flags.noclip &&
originalDock != scr->workspaces[scr->current_workspace]->clip)
allDocks[ i++ ] = scr->workspaces[scr->current_workspace]->clip;
for ( ; i < 2; i++) /* In case the clip, the dock, or both, are disabled */
allDocks[ i ] = NULL;
wins[0] = icon->core->window; wins[0] = icon->core->window;
wins[1] = scr->dock_shadow; wins[1] = scr->dock_shadow;
XRestackWindows(dpy, wins, 2); XRestackWindows(dpy, wins, 2);
XMoveResizeWindow(dpy, scr->dock_shadow, aicon->x_pos, aicon->y_pos, ICON_SIZE, ICON_SIZE);
if (superfluous) { if (superfluous) {
if (icon->pixmap != None) if (icon->pixmap != None)
ghost = MakeGhostIcon(scr, icon->pixmap); ghost = MakeGhostIcon(scr, icon->pixmap);
@@ -755,6 +808,8 @@ void appIconMouseDown(WObjDescriptor * desc, XEvent * event)
XSetWindowBackgroundPixmap(dpy, scr->dock_shadow, ghost); XSetWindowBackgroundPixmap(dpy, scr->dock_shadow, ghost);
XClearWindow(dpy, scr->dock_shadow); XClearWindow(dpy, scr->dock_shadow);
} }
if (ondock)
XMapWindow(dpy, scr->dock_shadow);
while (!done) { while (!done) {
WMMaskEvent(dpy, PointerMotionMask | ButtonReleaseMask | ButtonPressMask WMMaskEvent(dpy, PointerMotionMask | ButtonReleaseMask | ButtonPressMask
@@ -774,8 +829,8 @@ void appIconMouseDown(WObjDescriptor * desc, XEvent * event)
case MotionNotify: case MotionNotify:
hasMoved = True; hasMoved = True;
if (!grabbed) { if (!grabbed) {
if (abs(dx - ev.xmotion.x) >= MOVE_THRESHOLD if (abs(ofs_x - ev.xmotion.x) >= MOVE_THRESHOLD
|| abs(dy - ev.xmotion.y) >= MOVE_THRESHOLD) { || abs(ofs_y - ev.xmotion.y) >= MOVE_THRESHOLD) {
XChangeActivePointerGrab(dpy, ButtonMotionMask XChangeActivePointerGrab(dpy, ButtonMotionMask
| ButtonReleaseMask | ButtonPressMask, | ButtonReleaseMask | ButtonPressMask,
wCursor[WCUR_MOVE], CurrentTime); wCursor[WCUR_MOVE], CurrentTime);
@@ -784,68 +839,87 @@ void appIconMouseDown(WObjDescriptor * desc, XEvent * event)
break; break;
} }
} }
x = ev.xmotion.x_root - dx;
y = ev.xmotion.y_root - dy;
if (movingSingle) if (omnipresent && !showed_all_clips) {
XMoveWindow(dpy, icon->core->window, x, y); int i;
else for (i = 0; i < scr->workspace_count; i++) {
if (i == scr->current_workspace)
continue;
wDockShowIcons(scr->workspaces[i]->clip);
/* Note: if dock is collapsed (for instance, because it
auto-collapses), its icons still won't show up */
}
showed_all_clips = True; /* To prevent flickering */
}
x = ev.xmotion.x_root - ofs_x;
y = ev.xmotion.y_root - ofs_y;
wAppIconMove(aicon, x, y); wAppIconMove(aicon, x, y);
if (dockable) { /* At a high level, this if-block is about setting theNewDock to
if (scr->dock && wDockSnapIcon(scr->dock, aicon, x, y, &ix, &iy, False)) { * the first dock that could snap the appicon at the current
shad_x = scr->dock->x_pos + ix * wPreferences.icon_size; * position, and the next if-block uses that and other info to
shad_y = scr->dock->y_pos + iy * wPreferences.icon_size; * determine whether to dock/undock.
*/
if (scr->last_dock != scr->dock && collapsed) { WDock *theNewDock = NULL;
scr->last_dock->collapsed = 1; for (i = 0; dockable && i < 2; i++) {
wDockHideIcons(scr->last_dock); WDock *theDock = allDocks[i];
collapsed = 0; if (theDock == NULL)
break;
if (wDockSnapIcon(theDock, aicon, x, y, &ix, &iy, (theDock == originalDock))) {
theNewDock = theDock;
break;
} }
if (!collapsed && (collapsed = scr->dock->collapsed)) { }
scr->dock->collapsed = 0; if (originalDock != NULL && theNewDock == NULL &&
wDockShowIcons(scr->dock); (aicon->launching || aicon->lock || aicon->running)) {
/* In those cases, stay in lastDock if no dock really wants us */
theNewDock = lastDock;
}
if (theNewDock != NULL && !aicon->launching && !aicon->lock && ev.xmotion.state & MOD_MASK)
/* Mod is pressed: do not dock */
theNewDock = NULL;
if (lastDock != NULL && lastDock != theNewDock) {
/* Leave lastDock in the state we found it */
if (collapsed) {
lastDock->collapsed = 1;
wDockHideIcons(lastDock);
collapsed = False;
}
if (lastDock->auto_raise_lower) {
wDockLower(lastDock);
}
}
if (theNewDock != NULL) {
if (lastDock != theNewDock) {
collapsed = theNewDock->collapsed;
if (collapsed) {
theNewDock->collapsed = 0;
wDockShowIcons(theNewDock);
}
if (theNewDock->auto_raise_lower) {
wDockRaise(theNewDock);
/* And raise the moving tile above it */
wRaiseFrame(aicon->icon->core);
}
lastDock = theNewDock;
} }
if (scr->dock->auto_raise_lower) shad_x = lastDock->x_pos + ix*wPreferences.icon_size;
wDockRaise(scr->dock); shad_y = lastDock->y_pos + iy*wPreferences.icon_size;
scr->last_dock = scr->dock;
XMoveWindow(dpy, scr->dock_shadow, shad_x, shad_y); XMoveWindow(dpy, scr->dock_shadow, shad_x, shad_y);
if (!docking)
if (!ondock) {
XMapWindow(dpy, scr->dock_shadow); XMapWindow(dpy, scr->dock_shadow);
docking = 1;
} else if (workspace->clip &&
wDockSnapIcon(workspace->clip, aicon, x, y, &ix, &iy, False)) {
shad_x = workspace->clip->x_pos + ix * wPreferences.icon_size;
shad_y = workspace->clip->y_pos + iy * wPreferences.icon_size;
if (scr->last_dock != workspace->clip && collapsed) {
scr->last_dock->collapsed = 1;
wDockHideIcons(scr->last_dock);
collapsed = 0;
} }
if (!collapsed && (collapsed = workspace->clip->collapsed)) { ondock = 1;
workspace->clip->collapsed = 0; } else {
wDockShowIcons(workspace->clip); lastDock = theNewDock; // i.e., NULL
} if (ondock) {
if (workspace->clip->auto_raise_lower)
wDockRaise(workspace->clip);
scr->last_dock = workspace->clip;
XMoveWindow(dpy, scr->dock_shadow, shad_x, shad_y);
if (!docking)
XMapWindow(dpy, scr->dock_shadow);
docking = 1;
} else if (docking) {
XUnmapWindow(dpy, scr->dock_shadow); XUnmapWindow(dpy, scr->dock_shadow);
docking = 0;
} }
ondock = 0;
} }
break; break;
@@ -857,41 +931,63 @@ void appIconMouseDown(WObjDescriptor * desc, XEvent * event)
break; break;
XUngrabPointer(dpy, CurrentTime); XUngrabPointer(dpy, CurrentTime);
if (docking) { Bool docked = False;
Bool docked; if (ondock) {
/* icon is trying to be docked */
SlideWindow(icon->core->window, x, y, shad_x, shad_y); SlideWindow(icon->core->window, x, y, shad_x, shad_y);
XUnmapWindow(dpy, scr->dock_shadow); XUnmapWindow(dpy, scr->dock_shadow);
docked = wDockAttachIcon(scr->last_dock, aicon, ix, iy, False); if (originalDock == NULL) { // docking an undocked appicon
if (scr->last_dock->auto_collapse) docked = wDockAttachIcon(lastDock, aicon, ix, iy, False);
collapsed = 0;
if (workspace->clip &&
workspace->clip != scr->last_dock && workspace->clip->auto_raise_lower)
wDockLower(workspace->clip);
if (!docked) { if (!docked) {
/* If icon could not be docked, slide it back to the old /* AppIcon got rejected (happens only when we can't get the
* position */ command for that appicon, and the user cancels the
wInputDialog asking for one). Make the rejection obvious by
sliding the icon to its old position */
SlideWindow(icon->core->window, x, y, oldX, oldY); SlideWindow(icon->core->window, x, y, oldX, oldY);
} }
} else {
if (movingSingle) {
/* move back to its place */
SlideWindow(icon->core->window, x, y, oldX, oldY);
wAppIconMove(aicon, oldX, oldY);
} else {
XMoveWindow(dpy, icon->core->window, x, y);
aicon->x_pos = x;
aicon->y_pos = y;
} }
if (workspace->clip && workspace->clip->auto_raise_lower) else { // moving a docked appicon to a dock
wDockLower(workspace->clip); if (originalDock == lastDock) {
docked = True;
wDockReattachIcon(originalDock, aicon, ix, iy);
}
else {
docked = wDockMoveIconBetweenDocks(originalDock, lastDock, aicon, ix, iy);
if (!docked) {
/* Possible scenario: user moved an auto-attracted appicon
from the clip to the dock, and cancelled the wInputDialog
asking for a command */
SlideWindow(icon->core->window, x, y, oldX, oldY);
wDockReattachIcon(originalDock, aicon, aicon->xindex, aicon->yindex);
}
}
}
// No matter what happened above, check to lower lastDock
if (lastDock->auto_raise_lower)
wDockLower(lastDock);
/* If docked (or tried to dock) to a auto_collapsing dock, unset
* collapsed, so that wHandleAppIconMove doesn't collapse it
* right away (the timer will take care of it) */
if (lastDock->auto_collapse)
collapsed = 0;
}
else {
if (originalDock != NULL) { /* Detaching a docked appicon */
if (superfluous) {
if (!aicon->running && !wPreferences.no_animations) {
/* We need to deselect it, even if is deselected in
* wDockDetach(), because else DoKaboom() will fail.
*/
if (aicon->icon->selected)
wIconSelect(aicon->icon);
DoKaboom(scr, aicon->icon->core->window, x, y);
}
}
wDockDetach(originalDock, aicon);
}
} }
if (collapsed) { if (collapsed) {
scr->last_dock->collapsed = 1; lastDock->collapsed = 1;
wDockHideIcons(scr->last_dock); wDockHideIcons(lastDock);
collapsed = 0; collapsed = 0;
} }
if (superfluous) { if (superfluous) {
@@ -899,17 +995,21 @@ void appIconMouseDown(WObjDescriptor * desc, XEvent * event)
XFreePixmap(dpy, ghost); XFreePixmap(dpy, ghost);
XSetWindowBackground(dpy, scr->dock_shadow, scr->white_pixel); XSetWindowBackground(dpy, scr->dock_shadow, scr->white_pixel);
} }
if (showed_all_clips) {
if (wPreferences.auto_arrange_icons) int i;
for (i = 0; i < scr->workspace_count; i++) {
if (i == scr->current_workspace)
continue;
wDockHideIcons(scr->workspaces[i]->clip);
}
}
if (wPreferences.auto_arrange_icons && !(originalDock != NULL && docked))
/* Need to rearrange unless moving from dock to dock */
wArrangeIcons(scr, True); wArrangeIcons(scr, True);
return hasMoved;
if (wPreferences.single_click && !hasMoved)
iconDblClick(desc, event);
done = 1;
break;
} }
} }
return False; /* Never reached */
} }
/* This function save the application icon and store the path in the Dictionary */ /* This function save the application icon and store the path in the Dictionary */

View File

@@ -71,6 +71,7 @@ typedef struct WAppIcon {
WAppIcon *wAppIconCreateForDock(WScreen *scr, char *command, char *wm_instance, WAppIcon *wAppIconCreateForDock(WScreen *scr, char *command, char *wm_instance,
char *wm_class, int tile); char *wm_class, int tile);
Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event);
void wAppIconDestroy(WAppIcon *aicon); void wAppIconDestroy(WAppIcon *aicon);
void wAppIconPaint(WAppIcon *aicon); void wAppIconPaint(WAppIcon *aicon);

View File

@@ -105,8 +105,6 @@ static void clipLeave(WDock *dock);
static void handleClipChangeWorkspace(WScreen *scr, XEvent *event); static void handleClipChangeWorkspace(WScreen *scr, XEvent *event);
static Bool moveIconBetweenDocks(WDock *src, WDock *dest, WAppIcon *icon, int x, int y);
static void clipEnterNotify(WObjDescriptor *desc, XEvent *event); static void clipEnterNotify(WObjDescriptor *desc, XEvent *event);
static void clipLeaveNotify(WObjDescriptor *desc, XEvent *event); static void clipLeaveNotify(WObjDescriptor *desc, XEvent *event);
static void clipAutoCollapse(void *cdata); static void clipAutoCollapse(void *cdata);
@@ -115,7 +113,6 @@ static void launchDockedApplication(WAppIcon *btn, Bool withSelection);
static void clipAutoLower(void *cdata); static void clipAutoLower(void *cdata);
static void clipAutoRaise(void *cdata); static void clipAutoRaise(void *cdata);
static void reattachIcon(WDock *dock, WAppIcon *icon, int x, int y);
static WAppIcon *mainIconCreate(WScreen *scr, int type); static WAppIcon *mainIconCreate(WScreen *scr, int type);
static int onScreen(WScreen *scr, int x, int y); static int onScreen(WScreen *scr, int x, int y);
@@ -781,13 +778,13 @@ static void switchWSCommand(WMenu *menu, WMenuEntry *entry)
WM_ITERATE_ARRAY(selectedIcons, btn, iter) { WM_ITERATE_ARRAY(selectedIcons, btn, iter) {
if (wDockFindFreeSlot(dest, &x, &y)) { if (wDockFindFreeSlot(dest, &x, &y)) {
moveIconBetweenDocks(src, dest, btn, x, y); wDockMoveIconBetweenDocks(src, dest, btn, x, y);
XUnmapWindow(dpy, btn->icon->core->window); XUnmapWindow(dpy, btn->icon->core->window);
} }
} }
} else if (icon != scr->clip_icon) { } else if (icon != scr->clip_icon) {
if (wDockFindFreeSlot(dest, &x, &y)) { if (wDockFindFreeSlot(dest, &x, &y)) {
moveIconBetweenDocks(src, dest, icon, x, y); wDockMoveIconBetweenDocks(src, dest, icon, x, y);
XUnmapWindow(dpy, icon->icon->core->window); XUnmapWindow(dpy, icon->icon->core->window);
} }
} }
@@ -1961,7 +1958,7 @@ Bool wDockAttachIcon(WDock *dock, WAppIcon *icon, int x, int y, Bool update_icon
return True; return True;
} }
static void reattachIcon(WDock *dock, WAppIcon *icon, int x, int y) void wDockReattachIcon(WDock *dock, WAppIcon *icon, int x, int y)
{ {
int index; int index;
@@ -1978,7 +1975,7 @@ static void reattachIcon(WDock *dock, WAppIcon *icon, int x, int y)
icon->y_pos = dock->y_pos + y * ICON_SIZE; icon->y_pos = dock->y_pos + y * ICON_SIZE;
} }
static Bool moveIconBetweenDocks(WDock *src, WDock *dest, WAppIcon *icon, int x, int y) Bool wDockMoveIconBetweenDocks(WDock *src, WDock *dest, WAppIcon *icon, int x, int y)
{ {
WWindow *wwin; WWindow *wwin;
char *command = NULL; char *command = NULL;
@@ -2941,7 +2938,7 @@ void wClipUpdateForWorkspaceChange(WScreen *scr, int workspace)
WAppIconChain *chain = scr->global_icons; WAppIconChain *chain = scr->global_icons;
while (chain) { while (chain) {
moveIconBetweenDocks(chain->aicon->dock, wDockMoveIconBetweenDocks(chain->aicon->dock,
scr->workspaces[workspace]->clip, scr->workspaces[workspace]->clip,
chain->aicon, chain->aicon->xindex, chain->aicon->yindex); chain->aicon, chain->aicon->xindex, chain->aicon->yindex);
if (scr->workspaces[workspace]->clip->collapsed) if (scr->workspaces[workspace]->clip->collapsed)
@@ -3400,217 +3397,6 @@ static void handleDockMove(WDock *dock, WAppIcon *aicon, XEvent *event)
} }
} }
static Bool handleIconMove(WDock *dock, WAppIcon *aicon, XEvent *event)
{
WScreen *scr = dock->screen_ptr;
Window wins[2];
WIcon *icon = aicon->icon;
WDock *dock2 = NULL, *last_dock = dock, *clip = NULL;
int ondock, grabbed = 0, change_dock = 0, collapsed = 0;
XEvent ev;
int x = aicon->x_pos, y = aicon->y_pos;
int ofs_x = event->xbutton.x, ofs_y = event->xbutton.y;
int shad_x = x, shad_y = y;
int ix = aicon->xindex, iy = aicon->yindex;
int tmp;
Pixmap ghost = None;
Bool docked;
int superfluous = wPreferences.superfluous; /* we catch it to avoid problems */
int omnipresent = aicon->omnipresent; /* this must be cached!!! */
Bool showed_all_clips = False;
Bool hasMoved = False;
if (wPreferences.flags.noupdates)
return hasMoved;
if (XGrabPointer(dpy, icon->core->window, True, ButtonMotionMask
| ButtonReleaseMask | ButtonPressMask, GrabModeAsync,
GrabModeAsync, None, None, CurrentTime) != GrabSuccess) {
}
if (!(event->xbutton.state & MOD_MASK))
wRaiseFrame(icon->core);
if (!wPreferences.flags.noclip)
clip = scr->workspaces[scr->current_workspace]->clip;
if (dock == scr->dock && !wPreferences.flags.noclip)
dock2 = clip;
else if (dock != scr->dock && !wPreferences.flags.nodock)
dock2 = scr->dock;
wins[0] = icon->core->window;
wins[1] = scr->dock_shadow;
XRestackWindows(dpy, wins, 2);
XMoveResizeWindow(dpy, scr->dock_shadow, aicon->x_pos, aicon->y_pos, ICON_SIZE, ICON_SIZE);
if (superfluous) {
if (icon->pixmap != None)
ghost = MakeGhostIcon(scr, icon->pixmap);
else
ghost = MakeGhostIcon(scr, icon->core->window);
XSetWindowBackgroundPixmap(dpy, scr->dock_shadow, ghost);
XClearWindow(dpy, scr->dock_shadow);
}
XMapWindow(dpy, scr->dock_shadow);
ondock = 1;
while (1) {
XMaskEvent(dpy, PointerMotionMask | ButtonReleaseMask | ButtonPressMask
| ButtonMotionMask | ExposureMask, &ev);
switch (ev.type) {
case Expose:
WMHandleEvent(&ev);
break;
case MotionNotify:
hasMoved = True;
if (!grabbed) {
if (abs(ofs_x - ev.xmotion.x) >= MOVE_THRESHOLD
|| abs(ofs_y - ev.xmotion.y) >= MOVE_THRESHOLD) {
XChangeActivePointerGrab(dpy, ButtonMotionMask
| ButtonReleaseMask | ButtonPressMask,
wCursor[WCUR_MOVE], CurrentTime);
grabbed = 1;
} else {
break;
}
}
if (omnipresent && !showed_all_clips) {
int i;
for (i = 0; i < scr->workspace_count; i++) {
if (i == scr->current_workspace)
continue;
wDockShowIcons(scr->workspaces[i]->clip);
/* Note: if dock is collapsed (for instance,
because it auto-collapses), its icons
still won't show up */
}
showed_all_clips = True; /* To prevent flickering */
}
x = ev.xmotion.x_root - ofs_x;
y = ev.xmotion.y_root - ofs_y;
tmp = wDockSnapIcon(dock, aicon, x, y, &ix, &iy, True);
if (tmp && dock2) {
change_dock = 0;
if (last_dock != dock && collapsed) {
last_dock->collapsed = 1;
wDockHideIcons(last_dock);
collapsed = 0;
}
if (!collapsed && (collapsed = dock->collapsed)) {
dock->collapsed = 0;
wDockShowIcons(dock);
}
if (dock->auto_raise_lower)
wDockRaise(dock);
last_dock = dock;
} else if (dock2) {
tmp = wDockSnapIcon(dock2, aicon, x, y, &ix, &iy, False);
if (tmp) {
change_dock = 1;
if (last_dock != dock2 && collapsed) {
last_dock->collapsed = 1;
wDockHideIcons(last_dock);
collapsed = 0;
}
if (!collapsed && (collapsed = dock2->collapsed)) {
dock2->collapsed = 0;
wDockShowIcons(dock2);
}
if (dock2->auto_raise_lower)
wDockRaise(dock2);
last_dock = dock2;
}
}
if (aicon->launching || aicon->lock || (aicon->running && !(ev.xmotion.state & MOD_MASK))
|| (!aicon->running && tmp)) {
shad_x = last_dock->x_pos + ix * wPreferences.icon_size;
shad_y = last_dock->y_pos + iy * wPreferences.icon_size;
XMoveWindow(dpy, scr->dock_shadow, shad_x, shad_y);
if (!ondock)
XMapWindow(dpy, scr->dock_shadow);
ondock = 1;
} else {
if (ondock)
XUnmapWindow(dpy, scr->dock_shadow);
ondock = 0;
}
XMoveWindow(dpy, icon->core->window, x, y);
break;
case ButtonPress:
break;
case ButtonRelease:
if (ev.xbutton.button != event->xbutton.button)
break;
XUngrabPointer(dpy, CurrentTime);
if (ondock) {
SlideWindow(icon->core->window, x, y, shad_x, shad_y);
XUnmapWindow(dpy, scr->dock_shadow);
if (!change_dock) {
reattachIcon(dock, aicon, ix, iy);
if (clip && dock != clip && clip->auto_raise_lower)
wDockLower(clip);
} else {
docked = moveIconBetweenDocks(dock, dock2, aicon, ix, iy);
if (!docked) {
/* Slide it back if dock rejected it */
SlideWindow(icon->core->window, x, y, aicon->x_pos, aicon->y_pos);
reattachIcon(dock, aicon, aicon->xindex, aicon->yindex);
}
if (last_dock->type == WM_CLIP && last_dock->auto_collapse)
collapsed = 0;
}
} else {
aicon->x_pos = x;
aicon->y_pos = y;
if (superfluous) {
if (!aicon->running && !wPreferences.no_animations) {
/* We need to deselect it, even if is deselected in
* wDockDetach(), because else DoKaboom() will fail.
*/
if (aicon->icon->selected)
wIconSelect(aicon->icon);
DoKaboom(scr, aicon->icon->core->window, x, y);
}
}
if (clip && clip->auto_raise_lower)
wDockLower(clip);
wDockDetach(dock, aicon);
}
if (collapsed) {
last_dock->collapsed = 1;
wDockHideIcons(last_dock);
collapsed = 0;
}
if (superfluous) {
if (ghost != None)
XFreePixmap(dpy, ghost);
XSetWindowBackground(dpy, scr->dock_shadow, scr->white_pixel);
}
if (showed_all_clips) {
int i;
for (i = 0; i < scr->workspace_count; i++) {
if (i == scr->current_workspace)
continue;
wDockHideIcons(scr->workspaces[i]->clip);
}
}
return hasMoved;;
}
}
return False; /* never reached */
}
static int getClipButton(int px, int py) static int getClipButton(int px, int py)
{ {
@@ -3730,7 +3516,7 @@ static void iconMouseDown(WObjDescriptor *desc, XEvent *event)
else else
handleDockMove(dock, aicon, event); handleDockMove(dock, aicon, event);
} else { } else {
Bool hasMoved = handleIconMove(dock, aicon, event); Bool hasMoved = wHandleAppIconMove(aicon, event);
if (wPreferences.single_click && !hasMoved) if (wPreferences.single_click && !hasMoved)
iconDblClick(desc, event); iconDblClick(desc, event);
} }

View File

@@ -82,6 +82,8 @@ Bool wDockSnapIcon(WDock *dock, WAppIcon *icon, int req_x, int req_y,
int *ret_x, int *ret_y, int redocking); int *ret_x, int *ret_y, int redocking);
Bool wDockFindFreeSlot(WDock *dock, int *req_x, int *req_y); Bool wDockFindFreeSlot(WDock *dock, int *req_x, int *req_y);
void wDockDetach(WDock *dock, WAppIcon *icon); void wDockDetach(WDock *dock, WAppIcon *icon);
Bool wDockMoveIconBetweenDocks(WDock *src, WDock *dest, WAppIcon *icon, int x, int y);
void wDockReattachIcon(WDock *dock, WAppIcon *icon, int x, int y);
void wDockFinishLaunch(WDock *dock, WAppIcon *icon); void wDockFinishLaunch(WDock *dock, WAppIcon *icon);
void wDockTrackWindowLaunch(WDock *dock, Window window); void wDockTrackWindowLaunch(WDock *dock, Window window);