Change to the linux kernel coding style
[wmaker-crm.git] / src / appicon.c
blobe3164b73992d957487431ca3227e2daf06c58e87
1 /* appicon.c- icon for applications (not mini-window)
2 *
3 * Window Maker window manager
4 *
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * Copyright (c) 1998-2003 Dan Pascu
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 * USA.
22 */
24 #include "wconfig.h"
26 #include <X11/Xlib.h>
27 #include <X11/Xutil.h>
28 #include <stdlib.h>
29 #include <string.h>
31 #include "WindowMaker.h"
32 #include "wcore.h"
33 #include "window.h"
34 #include "icon.h"
35 #include "appicon.h"
36 #include "actions.h"
37 #include "stacking.h"
38 #include "dock.h"
39 #include "funcs.h"
40 #include "defaults.h"
41 #include "workspace.h"
42 #include "superfluous.h"
43 #include "menu.h"
44 #include "framewin.h"
45 #include "dialog.h"
46 #include "client.h"
47 #ifdef XDND
48 #include "xdnd.h"
49 #endif
50 #include "wsound.h"
52 /*
53 * icon_file for the dock is got from the preferences file by
54 * using the classname/instancename
55 */
57 /**** Global variables ****/
58 extern Cursor wCursor[WCUR_LAST];
59 extern WPreferences wPreferences;
61 #define MOD_MASK wPreferences.modifier_mask
63 void appIconMouseDown(WObjDescriptor * desc, XEvent * event);
64 static void iconDblClick(WObjDescriptor * desc, XEvent * event);
65 static void iconExpose(WObjDescriptor * desc, XEvent * event);
67 WAppIcon *wAppIconCreateForDock(WScreen * scr, char *command, char *wm_instance, char *wm_class, int tile)
68 {
69 WAppIcon *dicon;
70 char *path;
72 dicon = wmalloc(sizeof(WAppIcon));
73 wretain(dicon);
74 memset(dicon, 0, sizeof(WAppIcon));
75 dicon->yindex = -1;
76 dicon->xindex = -1;
78 dicon->prev = NULL;
79 dicon->next = scr->app_icon_list;
80 if (scr->app_icon_list) {
81 scr->app_icon_list->prev = dicon;
82 }
83 scr->app_icon_list = dicon;
85 if (command) {
86 dicon->command = wstrdup(command);
87 }
88 if (wm_class)
89 dicon->wm_class = wstrdup(wm_class);
90 if (wm_instance)
91 dicon->wm_instance = wstrdup(wm_instance);
93 path = wDefaultGetIconFile(scr, wm_instance, wm_class, True);
94 if (!path && command) {
95 wApplicationExtractDirPackIcon(scr, command, wm_instance, wm_class);
97 path = wDefaultGetIconFile(scr, wm_instance, wm_class, False);
98 }
100 if (path)
101 path = FindImage(wPreferences.icon_path, path);
103 dicon->icon = wIconCreateWithIconFile(scr, path, tile);
104 if (path)
105 wfree(path);
106 #ifdef XDND
107 wXDNDMakeAwareness(dicon->icon->core->window);
108 #endif
110 #ifdef DEMATERIALIZE_ICON
112 XSetWindowAttributes attribs;
113 attribs.save_under = True;
114 XChangeWindowAttributes(dpy, dicon->icon->core->window, CWSaveUnder, &attribs);
116 #endif
118 /* will be overriden by dock */
119 dicon->icon->core->descriptor.handle_mousedown = appIconMouseDown;
120 dicon->icon->core->descriptor.handle_expose = iconExpose;
121 dicon->icon->core->descriptor.parent_type = WCLASS_APPICON;
122 dicon->icon->core->descriptor.parent = dicon;
123 AddToStackList(dicon->icon->core);
125 return dicon;
128 WAppIcon *wAppIconCreate(WWindow * leader_win)
130 WAppIcon *aicon;
131 WScreen *scr = leader_win->screen_ptr;
133 aicon = wmalloc(sizeof(WAppIcon));
134 wretain(aicon);
135 memset(aicon, 0, sizeof(WAppIcon));
137 aicon->yindex = -1;
138 aicon->xindex = -1;
140 aicon->prev = NULL;
141 aicon->next = scr->app_icon_list;
142 if (scr->app_icon_list) {
143 scr->app_icon_list->prev = aicon;
145 scr->app_icon_list = aicon;
147 if (leader_win->wm_class)
148 aicon->wm_class = wstrdup(leader_win->wm_class);
149 if (leader_win->wm_instance)
150 aicon->wm_instance = wstrdup(leader_win->wm_instance);
152 aicon->icon = wIconCreate(leader_win);
153 #ifdef DEMATERIALIZE_ICON
155 XSetWindowAttributes attribs;
156 attribs.save_under = True;
157 XChangeWindowAttributes(dpy, aicon->icon->core->window, CWSaveUnder, &attribs);
159 #endif
160 #ifdef XDND
161 wXDNDMakeAwareness(aicon->icon->core->window);
162 #endif
164 /* will be overriden if docked */
165 aicon->icon->core->descriptor.handle_mousedown = appIconMouseDown;
166 aicon->icon->core->descriptor.handle_expose = iconExpose;
167 aicon->icon->core->descriptor.parent_type = WCLASS_APPICON;
168 aicon->icon->core->descriptor.parent = aicon;
169 AddToStackList(aicon->icon->core);
170 aicon->icon->show_title = 0;
171 wIconUpdate(aicon->icon);
173 return aicon;
176 void wAppIconDestroy(WAppIcon * aicon)
178 WScreen *scr = aicon->icon->core->screen_ptr;
180 RemoveFromStackList(aicon->icon->core);
181 wIconDestroy(aicon->icon);
182 if (aicon->command)
183 wfree(aicon->command);
184 #ifdef XDND
185 if (aicon->dnd_command)
186 wfree(aicon->dnd_command);
187 #endif
188 if (aicon->wm_instance)
189 wfree(aicon->wm_instance);
190 if (aicon->wm_class)
191 wfree(aicon->wm_class);
193 if (aicon == scr->app_icon_list) {
194 if (aicon->next)
195 aicon->next->prev = NULL;
196 scr->app_icon_list = aicon->next;
197 } else {
198 if (aicon->next)
199 aicon->next->prev = aicon->prev;
200 if (aicon->prev)
201 aicon->prev->next = aicon->next;
204 aicon->destroyed = 1;
205 wrelease(aicon);
208 #ifdef NEWAPPICON
209 static void drawCorner(WIcon * icon, WWindow * wwin, int active)
211 WScreen *scr = wwin->screen_ptr;
212 XPoint points[3];
213 GC gc;
215 points[0].x = 2;
216 points[0].y = 2;
217 points[1].x = 12;
218 points[1].y = 2;
219 points[2].x = 2;
220 points[2].y = 12;
221 if (active) {
222 gc = scr->focused_texture->any.gc;
223 } else {
224 gc = scr->unfocused_texture->any.gc;
226 XFillPolygon(dpy, icon->core->window, gc, points, 3, Convex, CoordModeOrigin);
228 #endif /* NEWAPPICON */
230 static void drawCorner(WIcon * icon)
232 WScreen *scr = icon->core->screen_ptr;
233 XPoint points[3];
235 points[0].x = 1;
236 points[0].y = 1;
237 points[1].x = 12;
238 points[1].y = 1;
239 points[2].x = 1;
240 points[2].y = 12;
241 XFillPolygon(dpy, icon->core->window, scr->icon_title_texture->normal_gc,
242 points, 3, Convex, CoordModeOrigin);
243 XDrawLine(dpy, icon->core->window, scr->icon_title_texture->light_gc, 0, 0, 0, 12);
244 XDrawLine(dpy, icon->core->window, scr->icon_title_texture->light_gc, 0, 0, 12, 0);
245 /* drawing the second line gives a weird concave look. -Dan */
246 #if 0
247 XDrawLine(dpy, icon->core->window, scr->icon_title_texture->light_gc, 1, 1, 1, 11);
248 XDrawLine(dpy, icon->core->window, scr->icon_title_texture->light_gc, 1, 1, 11, 1);
249 #endif
252 void wAppIconMove(WAppIcon * aicon, int x, int y)
254 XMoveWindow(dpy, aicon->icon->core->window, x, y);
255 aicon->x_pos = x;
256 aicon->y_pos = y;
259 #ifdef WS_INDICATOR
260 static void updateDockNumbers(WScreen * scr)
262 int length;
263 char *ws_numbers;
264 WAppIcon *dicon = scr->dock->icon_array[0];
266 ws_numbers = wmalloc(20);
267 snprintf(ws_numbers, 20, "%i [ %i ]", scr->current_workspace + 1, ((scr->current_workspace / 10) + 1));
268 length = strlen(ws_numbers);
270 XClearArea(dpy, dicon->icon->core->window, 2, 2, 50, WMFontHeight(scr->icon_title_font) + 1, False);
272 WMDrawString(scr->wmscreen, dicon->icon->core->window, scr->black,
273 scr->icon_title_font, 4, 3, ws_numbers, length);
275 WMDrawString(scr->wmscreen, dicon->icon->core->window, scr->white,
276 scr->icon_title_font, 3, 2, ws_numbers, length);
278 wfree(ws_numbers);
280 #endif /* WS_INDICATOR */
282 void wAppIconPaint(WAppIcon * aicon)
284 WApplication *wapp;
285 WScreen *scr = aicon->icon->core->screen_ptr;
287 if (aicon->icon->owner)
288 wapp = wApplicationOf(aicon->icon->owner->main_window);
289 else
290 wapp = NULL;
292 wIconPaint(aicon->icon);
294 # ifdef WS_INDICATOR
295 if (aicon->docked && scr->dock && scr->dock == aicon->dock && aicon->yindex == 0)
296 updateDockNumbers(scr);
297 # endif
298 if (scr->dock_dots && aicon->docked && !aicon->running && aicon->command != NULL) {
299 XSetClipMask(dpy, scr->copy_gc, scr->dock_dots->mask);
300 XSetClipOrigin(dpy, scr->copy_gc, 0, 0);
301 XCopyArea(dpy, scr->dock_dots->image, aicon->icon->core->window,
302 scr->copy_gc, 0, 0, scr->dock_dots->width, scr->dock_dots->height, 0, 0);
304 #ifdef HIDDENDOT
305 if (wapp && wapp->flags.hidden) {
306 XSetClipMask(dpy, scr->copy_gc, scr->dock_dots->mask);
307 XSetClipOrigin(dpy, scr->copy_gc, 0, 0);
308 XCopyArea(dpy, scr->dock_dots->image,
309 aicon->icon->core->window, scr->copy_gc, 0, 0, 7, scr->dock_dots->height, 0, 0);
311 #endif /* HIDDENDOT */
313 if (aicon->omnipresent)
314 drawCorner(aicon->icon);
316 XSetClipMask(dpy, scr->copy_gc, None);
317 if (aicon->launching) {
318 XFillRectangle(dpy, aicon->icon->core->window, scr->stipple_gc,
319 0, 0, wPreferences.icon_size, wPreferences.icon_size);
323 #define canBeDocked(wwin) ((wwin) && ((wwin)->wm_class||(wwin)->wm_instance))
325 static void hideCallback(WMenu * menu, WMenuEntry * entry)
327 WApplication *wapp = (WApplication *) entry->clientdata;
329 if (wapp->flags.hidden) {
330 wWorkspaceChange(menu->menu->screen_ptr, wapp->last_workspace);
331 wUnhideApplication(wapp, False, False);
332 } else {
333 wHideApplication(wapp);
337 static void unhideHereCallback(WMenu * menu, WMenuEntry * entry)
339 WApplication *wapp = (WApplication *) entry->clientdata;
341 wUnhideApplication(wapp, False, True);
344 static void setIconCallback(WMenu * menu, WMenuEntry * entry)
346 WAppIcon *icon = ((WApplication *) entry->clientdata)->app_icon;
347 char *file = NULL;
348 WScreen *scr;
349 int result;
351 assert(icon != NULL);
353 if (icon->editing)
354 return;
355 icon->editing = 1;
356 scr = icon->icon->core->screen_ptr;
358 wretain(icon);
360 result = wIconChooserDialog(scr, &file, icon->wm_instance, icon->wm_class);
362 if (result && !icon->destroyed) {
363 if (file && *file == 0) {
364 wfree(file);
365 file = NULL;
367 if (!wIconChangeImageFile(icon->icon, file)) {
368 wMessageDialog(scr, _("Error"),
369 _("Could not open specified icon file"), _("OK"), NULL, NULL);
370 } else {
371 wDefaultChangeIcon(scr, icon->wm_instance, icon->wm_class, file);
372 wAppIconPaint(icon);
374 if (file)
375 wfree(file);
377 icon->editing = 0;
378 wrelease(icon);
381 static void killCallback(WMenu * menu, WMenuEntry * entry)
383 WApplication *wapp = (WApplication *) entry->clientdata;
384 WFakeGroupLeader *fPtr;
385 char *buffer;
387 if (!WCHECK_STATE(WSTATE_NORMAL))
388 return;
390 WCHANGE_STATE(WSTATE_MODAL);
392 assert(entry->clientdata != NULL);
394 buffer = wstrconcat(wapp->app_icon ? wapp->app_icon->wm_class : NULL,
395 _(" will be forcibly closed.\n"
396 "Any unsaved changes will be lost.\n" "Please confirm."));
398 fPtr = wapp->main_window_desc->fake_group;
400 wretain(wapp->main_window_desc);
401 if (wPreferences.dont_confirm_kill
402 || wMessageDialog(menu->frame->screen_ptr, _("Kill Application"),
403 buffer, _("Yes"), _("No"), NULL) == WAPRDefault) {
404 if (fPtr != NULL) {
405 WWindow *wwin, *twin;
407 wwin = wapp->main_window_desc->screen_ptr->focused_window;
408 while (wwin) {
409 twin = wwin->prev;
410 if (wwin->fake_group == fPtr) {
411 wClientKill(wwin);
413 wwin = twin;
415 } else if (!wapp->main_window_desc->flags.destroyed) {
416 wClientKill(wapp->main_window_desc);
419 wrelease(wapp->main_window_desc);
421 wfree(buffer);
423 WCHANGE_STATE(WSTATE_NORMAL);
426 static WMenu *createApplicationMenu(WScreen * scr)
428 WMenu *menu;
430 menu = wMenuCreate(scr, NULL, False);
431 wMenuAddCallback(menu, _("Unhide Here"), unhideHereCallback, NULL);
432 wMenuAddCallback(menu, _("Hide"), hideCallback, NULL);
433 wMenuAddCallback(menu, _("Set Icon..."), setIconCallback, NULL);
434 wMenuAddCallback(menu, _("Kill"), killCallback, NULL);
436 return menu;
439 static void openApplicationMenu(WApplication * wapp, int x, int y)
441 WMenu *menu;
442 WScreen *scr = wapp->main_window_desc->screen_ptr;
443 int i;
445 if (!scr->icon_menu) {
446 scr->icon_menu = createApplicationMenu(scr);
447 wfree(scr->icon_menu->entries[1]->text);
450 menu = scr->icon_menu;
452 if (wapp->flags.hidden) {
453 menu->entries[1]->text = _("Unhide");
454 } else {
455 menu->entries[1]->text = _("Hide");
458 menu->flags.realized = 0;
459 wMenuRealize(menu);
461 x -= menu->frame->core->width / 2;
462 if (x + menu->frame->core->width > scr->scr_width)
463 x = scr->scr_width - menu->frame->core->width;
464 if (x < 0)
465 x = 0;
467 /* set client data */
468 for (i = 0; i < menu->entry_no; i++) {
469 menu->entries[i]->clientdata = wapp;
471 wMenuMapAt(menu, x, y, False);
474 /******************************************************************/
476 static void iconExpose(WObjDescriptor * desc, XEvent * event)
478 wAppIconPaint(desc->parent);
481 static void iconDblClick(WObjDescriptor * desc, XEvent * event)
483 WAppIcon *aicon = desc->parent;
484 WApplication *wapp;
485 WScreen *scr = aicon->icon->core->screen_ptr;
486 int unhideHere;
488 assert(aicon->icon->owner != NULL);
490 wapp = wApplicationOf(aicon->icon->owner->main_window);
491 #ifdef DEBUG0
492 if (!wapp) {
493 wwarning("could not find application descriptor for app icon!!");
494 return;
496 #endif
498 unhideHere = (event->xbutton.state & ShiftMask);
500 /* go to the last workspace that the user worked on the app */
501 if (!unhideHere && wapp->last_workspace != scr->current_workspace)
502 wWorkspaceChange(scr, wapp->last_workspace);
504 wUnhideApplication(wapp, event->xbutton.button == Button2, unhideHere);
506 if (event->xbutton.state & MOD_MASK) {
507 wHideOtherApplications(aicon->icon->owner);
511 void appIconMouseDown(WObjDescriptor * desc, XEvent * event)
513 WAppIcon *aicon = desc->parent;
514 WIcon *icon = aicon->icon;
515 XEvent ev;
516 int x = aicon->x_pos, y = aicon->y_pos;
517 int dx = event->xbutton.x, dy = event->xbutton.y;
518 int grabbed = 0;
519 int done = 0;
520 int superfluous = wPreferences.superfluous; /* we catch it to avoid problems */
521 WScreen *scr = icon->core->screen_ptr;
522 WWorkspace *workspace = scr->workspaces[scr->current_workspace];
523 int shad_x = 0, shad_y = 0, docking = 0, dockable, collapsed = 0;
524 int ix, iy;
525 int clickButton = event->xbutton.button;
526 Pixmap ghost = None;
527 Window wins[2];
528 Bool movingSingle = False;
529 int oldX = x;
530 int oldY = y;
532 if (aicon->editing || WCHECK_STATE(WSTATE_MODAL))
533 return;
535 if (IsDoubleClick(scr, event)) {
536 iconDblClick(desc, event);
537 return;
540 if (event->xbutton.button == Button3) {
541 WObjDescriptor *desc;
542 WApplication *wapp = wApplicationOf(aicon->icon->owner->main_window);
544 if (!wapp)
545 return;
547 if (event->xbutton.send_event &&
548 XGrabPointer(dpy, aicon->icon->core->window, True, ButtonMotionMask
549 | ButtonReleaseMask | ButtonPressMask, GrabModeAsync,
550 GrabModeAsync, None, None, CurrentTime) != GrabSuccess) {
551 wwarning("pointer grab failed for appicon menu");
552 return;
555 openApplicationMenu(wapp, event->xbutton.x_root, event->xbutton.y_root);
557 /* allow drag select of menu */
558 desc = &scr->icon_menu->menu->descriptor;
559 event->xbutton.send_event = True;
560 (*desc->handle_mousedown) (desc, event);
561 return;
563 #ifdef DEBUG
564 puts("Moving icon");
565 #endif
566 if (event->xbutton.state & MOD_MASK)
567 wLowerFrame(icon->core);
568 else
569 wRaiseFrame(icon->core);
571 if (XGrabPointer(dpy, icon->core->window, True, ButtonMotionMask
572 | ButtonReleaseMask | ButtonPressMask, GrabModeAsync,
573 GrabModeAsync, None, None, CurrentTime) != GrabSuccess) {
574 wwarning("pointer grab failed for appicon move");
577 if (wPreferences.flags.nodock && wPreferences.flags.noclip)
578 dockable = 0;
579 else
580 dockable = canBeDocked(icon->owner);
582 wins[0] = icon->core->window;
583 wins[1] = scr->dock_shadow;
584 XRestackWindows(dpy, wins, 2);
585 if (superfluous) {
586 if (icon->pixmap != None)
587 ghost = MakeGhostIcon(scr, icon->pixmap);
588 else
589 ghost = MakeGhostIcon(scr, icon->core->window);
590 XSetWindowBackgroundPixmap(dpy, scr->dock_shadow, ghost);
591 XClearWindow(dpy, scr->dock_shadow);
594 while (!done) {
595 WMMaskEvent(dpy, PointerMotionMask | ButtonReleaseMask | ButtonPressMask
596 | ButtonMotionMask | ExposureMask, &ev);
597 switch (ev.type) {
598 case Expose:
599 WMHandleEvent(&ev);
600 break;
602 case MotionNotify:
603 if (!grabbed) {
604 if (abs(dx - ev.xmotion.x) >= MOVE_THRESHOLD
605 || abs(dy - ev.xmotion.y) >= MOVE_THRESHOLD) {
606 XChangeActivePointerGrab(dpy, ButtonMotionMask
607 | ButtonReleaseMask | ButtonPressMask,
608 wCursor[WCUR_MOVE], CurrentTime);
609 grabbed = 1;
610 } else {
611 break;
614 x = ev.xmotion.x_root - dx;
615 y = ev.xmotion.y_root - dy;
617 if (movingSingle) {
618 XMoveWindow(dpy, icon->core->window, x, y);
619 } else {
620 wAppIconMove(aicon, x, y);
623 if (dockable) {
624 if (scr->dock && wDockSnapIcon(scr->dock, aicon, x, y, &ix, &iy, False)) {
625 shad_x = scr->dock->x_pos + ix * wPreferences.icon_size;
626 shad_y = scr->dock->y_pos + iy * wPreferences.icon_size;
628 if (scr->last_dock != scr->dock && collapsed) {
629 scr->last_dock->collapsed = 1;
630 wDockHideIcons(scr->last_dock);
631 collapsed = 0;
633 if (!collapsed && (collapsed = scr->dock->collapsed)) {
634 scr->dock->collapsed = 0;
635 wDockShowIcons(scr->dock);
638 if (scr->dock->auto_raise_lower)
639 wDockRaise(scr->dock);
641 scr->last_dock = scr->dock;
643 XMoveWindow(dpy, scr->dock_shadow, shad_x, shad_y);
644 if (!docking) {
645 XMapWindow(dpy, scr->dock_shadow);
647 docking = 1;
648 } else if (workspace->clip &&
649 wDockSnapIcon(workspace->clip, aicon, x, y, &ix, &iy, False)) {
650 shad_x = workspace->clip->x_pos + ix * wPreferences.icon_size;
651 shad_y = workspace->clip->y_pos + iy * wPreferences.icon_size;
653 if (scr->last_dock != workspace->clip && collapsed) {
654 scr->last_dock->collapsed = 1;
655 wDockHideIcons(scr->last_dock);
656 collapsed = 0;
658 if (!collapsed && (collapsed = workspace->clip->collapsed)) {
659 workspace->clip->collapsed = 0;
660 wDockShowIcons(workspace->clip);
663 if (workspace->clip->auto_raise_lower)
664 wDockRaise(workspace->clip);
666 scr->last_dock = workspace->clip;
668 XMoveWindow(dpy, scr->dock_shadow, shad_x, shad_y);
669 if (!docking) {
670 XMapWindow(dpy, scr->dock_shadow);
672 docking = 1;
673 } else if (docking) {
674 XUnmapWindow(dpy, scr->dock_shadow);
675 docking = 0;
679 break;
681 case ButtonPress:
682 break;
684 case ButtonRelease:
685 if (ev.xbutton.button != clickButton)
686 break;
687 XUngrabPointer(dpy, CurrentTime);
689 if (docking) {
690 Bool docked;
692 /* icon is trying to be docked */
693 SlideWindow(icon->core->window, x, y, shad_x, shad_y);
694 XUnmapWindow(dpy, scr->dock_shadow);
695 docked = wDockAttachIcon(scr->last_dock, aicon, ix, iy);
696 if (scr->last_dock->auto_collapse) {
697 collapsed = 0;
699 if (workspace->clip &&
700 workspace->clip != scr->last_dock && workspace->clip->auto_raise_lower)
701 wDockLower(workspace->clip);
703 if (!docked) {
704 /* If icon could not be docked, slide it back to the old
705 * position */
706 SlideWindow(icon->core->window, x, y, oldX, oldY);
709 wSoundPlay(WSOUND_DOCK);
710 } else {
711 if (movingSingle) {
712 /* move back to its place */
713 SlideWindow(icon->core->window, x, y, oldX, oldY);
714 wAppIconMove(aicon, oldX, oldY);
715 } else {
716 XMoveWindow(dpy, icon->core->window, x, y);
717 aicon->x_pos = x;
718 aicon->y_pos = y;
720 if (workspace->clip && workspace->clip->auto_raise_lower)
721 wDockLower(workspace->clip);
723 if (collapsed) {
724 scr->last_dock->collapsed = 1;
725 wDockHideIcons(scr->last_dock);
726 collapsed = 0;
728 if (superfluous) {
729 if (ghost != None)
730 XFreePixmap(dpy, ghost);
731 XSetWindowBackground(dpy, scr->dock_shadow, scr->white_pixel);
734 if (wPreferences.auto_arrange_icons)
735 wArrangeIcons(scr, True);
737 done = 1;
738 break;
741 #ifdef DEBUG
742 puts("End icon move");
743 #endif