Maximus: Tiled Maximization
[wmaker-crm.git] / src / appicon.c
blob05a8485de79bbc24d43975a2572bc22af5d0b6f8
1 /* appicon.c- icon for applications (not mini-window)
3 * Window Maker window manager
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * Copyright (c) 1998-2003 Dan Pascu
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.
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.
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.
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"
53 * icon_file for the dock is got from the preferences file by
54 * using the classname/instancename
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)
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;
83 scr->app_icon_list = dicon;
85 if (command) {
86 dicon->command = wstrdup(command);
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);
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;
386 char *shortname;
387 char *basename(const char *shortname);
389 if (!WCHECK_STATE(WSTATE_NORMAL))
390 return;
392 WCHANGE_STATE(WSTATE_MODAL);
394 assert(entry->clientdata != NULL);
396 shortname = basename(wapp->app_icon->wm_instance);
398 buffer = wstrconcat(wapp->app_icon ? shortname : NULL,
399 _(" will be forcibly closed.\n"
400 "Any unsaved changes will be lost.\n" "Please confirm."));
402 fPtr = wapp->main_window_desc->fake_group;
404 wretain(wapp->main_window_desc);
405 if (wPreferences.dont_confirm_kill
406 || wMessageDialog(menu->frame->screen_ptr, _("Kill Application"),
407 buffer, _("Yes"), _("No"), NULL) == WAPRDefault) {
408 if (fPtr != NULL) {
409 WWindow *wwin, *twin;
411 wwin = wapp->main_window_desc->screen_ptr->focused_window;
412 while (wwin) {
413 twin = wwin->prev;
414 if (wwin->fake_group == fPtr) {
415 wClientKill(wwin);
417 wwin = twin;
419 } else if (!wapp->main_window_desc->flags.destroyed) {
420 wClientKill(wapp->main_window_desc);
423 wrelease(wapp->main_window_desc);
425 wfree(buffer);
427 WCHANGE_STATE(WSTATE_NORMAL);
430 static WMenu *createApplicationMenu(WScreen * scr)
432 WMenu *menu;
434 menu = wMenuCreate(scr, NULL, False);
435 wMenuAddCallback(menu, _("Unhide Here"), unhideHereCallback, NULL);
436 wMenuAddCallback(menu, _("Hide"), hideCallback, NULL);
437 wMenuAddCallback(menu, _("Set Icon..."), setIconCallback, NULL);
438 wMenuAddCallback(menu, _("Kill"), killCallback, NULL);
440 return menu;
443 static void openApplicationMenu(WApplication * wapp, int x, int y)
445 WMenu *menu;
446 WScreen *scr = wapp->main_window_desc->screen_ptr;
447 int i;
449 if (!scr->icon_menu) {
450 scr->icon_menu = createApplicationMenu(scr);
451 wfree(scr->icon_menu->entries[1]->text);
454 menu = scr->icon_menu;
456 if (wapp->flags.hidden) {
457 menu->entries[1]->text = _("Unhide");
458 } else {
459 menu->entries[1]->text = _("Hide");
462 menu->flags.realized = 0;
463 wMenuRealize(menu);
465 x -= menu->frame->core->width / 2;
466 if (x + menu->frame->core->width > scr->scr_width)
467 x = scr->scr_width - menu->frame->core->width;
468 if (x < 0)
469 x = 0;
471 /* set client data */
472 for (i = 0; i < menu->entry_no; i++) {
473 menu->entries[i]->clientdata = wapp;
475 wMenuMapAt(menu, x, y, False);
478 /******************************************************************/
480 static void iconExpose(WObjDescriptor * desc, XEvent * event)
482 wAppIconPaint(desc->parent);
485 static void iconDblClick(WObjDescriptor * desc, XEvent * event)
487 WAppIcon *aicon = desc->parent;
488 WApplication *wapp;
489 WScreen *scr = aicon->icon->core->screen_ptr;
490 int unhideHere;
492 assert(aicon->icon->owner != NULL);
494 wapp = wApplicationOf(aicon->icon->owner->main_window);
495 #ifdef DEBUG0
496 if (!wapp) {
497 wwarning("could not find application descriptor for app icon!!");
498 return;
500 #endif
502 unhideHere = (event->xbutton.state & ShiftMask);
504 /* go to the last workspace that the user worked on the app */
505 if (!unhideHere && wapp->last_workspace != scr->current_workspace)
506 wWorkspaceChange(scr, wapp->last_workspace);
508 wUnhideApplication(wapp, event->xbutton.button == Button2, unhideHere);
510 if (event->xbutton.state & MOD_MASK) {
511 wHideOtherApplications(aicon->icon->owner);
515 void appIconMouseDown(WObjDescriptor * desc, XEvent * event)
517 WAppIcon *aicon = desc->parent;
518 WIcon *icon = aicon->icon;
519 XEvent ev;
520 int x = aicon->x_pos, y = aicon->y_pos;
521 int dx = event->xbutton.x, dy = event->xbutton.y;
522 int grabbed = 0;
523 int done = 0;
524 int superfluous = wPreferences.superfluous; /* we catch it to avoid problems */
525 WScreen *scr = icon->core->screen_ptr;
526 WWorkspace *workspace = scr->workspaces[scr->current_workspace];
527 int shad_x = 0, shad_y = 0, docking = 0, dockable, collapsed = 0;
528 int ix, iy;
529 int clickButton = event->xbutton.button;
530 Pixmap ghost = None;
531 Window wins[2];
532 Bool movingSingle = False;
533 int oldX = x;
534 int oldY = y;
536 if (aicon->editing || WCHECK_STATE(WSTATE_MODAL))
537 return;
539 if (IsDoubleClick(scr, event)) {
540 iconDblClick(desc, event);
541 return;
544 if (event->xbutton.button == Button3) {
545 WObjDescriptor *desc;
546 WApplication *wapp = wApplicationOf(aicon->icon->owner->main_window);
548 if (!wapp)
549 return;
551 if (event->xbutton.send_event &&
552 XGrabPointer(dpy, aicon->icon->core->window, True, ButtonMotionMask
553 | ButtonReleaseMask | ButtonPressMask, GrabModeAsync,
554 GrabModeAsync, None, None, CurrentTime) != GrabSuccess) {
555 wwarning("pointer grab failed for appicon menu");
556 return;
559 openApplicationMenu(wapp, event->xbutton.x_root, event->xbutton.y_root);
561 /* allow drag select of menu */
562 desc = &scr->icon_menu->menu->descriptor;
563 event->xbutton.send_event = True;
564 (*desc->handle_mousedown) (desc, event);
565 return;
567 #ifdef DEBUG
568 puts("Moving icon");
569 #endif
570 if (event->xbutton.state & MOD_MASK)
571 wLowerFrame(icon->core);
572 else
573 wRaiseFrame(icon->core);
575 if (XGrabPointer(dpy, icon->core->window, True, ButtonMotionMask
576 | ButtonReleaseMask | ButtonPressMask, GrabModeAsync,
577 GrabModeAsync, None, None, CurrentTime) != GrabSuccess) {
578 wwarning("pointer grab failed for appicon move");
581 if (wPreferences.flags.nodock && wPreferences.flags.noclip)
582 dockable = 0;
583 else
584 dockable = canBeDocked(icon->owner);
586 wins[0] = icon->core->window;
587 wins[1] = scr->dock_shadow;
588 XRestackWindows(dpy, wins, 2);
589 if (superfluous) {
590 if (icon->pixmap != None)
591 ghost = MakeGhostIcon(scr, icon->pixmap);
592 else
593 ghost = MakeGhostIcon(scr, icon->core->window);
594 XSetWindowBackgroundPixmap(dpy, scr->dock_shadow, ghost);
595 XClearWindow(dpy, scr->dock_shadow);
598 while (!done) {
599 WMMaskEvent(dpy, PointerMotionMask | ButtonReleaseMask | ButtonPressMask
600 | ButtonMotionMask | ExposureMask | EnterWindowMask, &ev);
601 switch (ev.type) {
602 case Expose:
603 WMHandleEvent(&ev);
604 break;
606 case EnterNotify:
607 /* It means the cursor moved so fast that it entered
608 * something else (if moving slowly, it would have
609 * stayed in the appIcon that is being moved. Ignore
610 * such "spurious" EnterNotifiy's */
611 break;
613 case MotionNotify:
614 if (!grabbed) {
615 if (abs(dx - ev.xmotion.x) >= MOVE_THRESHOLD
616 || abs(dy - ev.xmotion.y) >= MOVE_THRESHOLD) {
617 XChangeActivePointerGrab(dpy, ButtonMotionMask
618 | ButtonReleaseMask | ButtonPressMask,
619 wCursor[WCUR_MOVE], CurrentTime);
620 grabbed = 1;
621 } else {
622 break;
625 x = ev.xmotion.x_root - dx;
626 y = ev.xmotion.y_root - dy;
628 if (movingSingle) {
629 XMoveWindow(dpy, icon->core->window, x, y);
630 } else {
631 wAppIconMove(aicon, x, y);
634 if (dockable) {
635 if (scr->dock && wDockSnapIcon(scr->dock, aicon, x, y, &ix, &iy, False)) {
636 shad_x = scr->dock->x_pos + ix * wPreferences.icon_size;
637 shad_y = scr->dock->y_pos + iy * wPreferences.icon_size;
639 if (scr->last_dock != scr->dock && collapsed) {
640 scr->last_dock->collapsed = 1;
641 wDockHideIcons(scr->last_dock);
642 collapsed = 0;
644 if (!collapsed && (collapsed = scr->dock->collapsed)) {
645 scr->dock->collapsed = 0;
646 wDockShowIcons(scr->dock);
649 if (scr->dock->auto_raise_lower)
650 wDockRaise(scr->dock);
652 scr->last_dock = scr->dock;
654 XMoveWindow(dpy, scr->dock_shadow, shad_x, shad_y);
655 if (!docking) {
656 XMapWindow(dpy, scr->dock_shadow);
658 docking = 1;
659 } else if (workspace->clip &&
660 wDockSnapIcon(workspace->clip, aicon, x, y, &ix, &iy, False)) {
661 shad_x = workspace->clip->x_pos + ix * wPreferences.icon_size;
662 shad_y = workspace->clip->y_pos + iy * wPreferences.icon_size;
664 if (scr->last_dock != workspace->clip && collapsed) {
665 scr->last_dock->collapsed = 1;
666 wDockHideIcons(scr->last_dock);
667 collapsed = 0;
669 if (!collapsed && (collapsed = workspace->clip->collapsed)) {
670 workspace->clip->collapsed = 0;
671 wDockShowIcons(workspace->clip);
674 if (workspace->clip->auto_raise_lower)
675 wDockRaise(workspace->clip);
677 scr->last_dock = workspace->clip;
679 XMoveWindow(dpy, scr->dock_shadow, shad_x, shad_y);
680 if (!docking) {
681 XMapWindow(dpy, scr->dock_shadow);
683 docking = 1;
684 } else if (docking) {
685 XUnmapWindow(dpy, scr->dock_shadow);
686 docking = 0;
690 break;
692 case ButtonPress:
693 break;
695 case ButtonRelease:
696 if (ev.xbutton.button != clickButton)
697 break;
698 XUngrabPointer(dpy, CurrentTime);
700 if (docking) {
701 Bool docked;
703 /* icon is trying to be docked */
704 SlideWindow(icon->core->window, x, y, shad_x, shad_y);
705 XUnmapWindow(dpy, scr->dock_shadow);
706 docked = wDockAttachIcon(scr->last_dock, aicon, ix, iy);
707 if (scr->last_dock->auto_collapse) {
708 collapsed = 0;
710 if (workspace->clip &&
711 workspace->clip != scr->last_dock && workspace->clip->auto_raise_lower)
712 wDockLower(workspace->clip);
714 if (!docked) {
715 /* If icon could not be docked, slide it back to the old
716 * position */
717 SlideWindow(icon->core->window, x, y, oldX, oldY);
720 wSoundPlay(WSOUND_DOCK);
721 } else {
722 if (movingSingle) {
723 /* move back to its place */
724 SlideWindow(icon->core->window, x, y, oldX, oldY);
725 wAppIconMove(aicon, oldX, oldY);
726 } else {
727 XMoveWindow(dpy, icon->core->window, x, y);
728 aicon->x_pos = x;
729 aicon->y_pos = y;
731 if (workspace->clip && workspace->clip->auto_raise_lower)
732 wDockLower(workspace->clip);
734 if (collapsed) {
735 scr->last_dock->collapsed = 1;
736 wDockHideIcons(scr->last_dock);
737 collapsed = 0;
739 if (superfluous) {
740 if (ghost != None)
741 XFreePixmap(dpy, ghost);
742 XSetWindowBackground(dpy, scr->dock_shadow, scr->white_pixel);
745 if (wPreferences.auto_arrange_icons)
746 wArrangeIcons(scr, True);
748 done = 1;
749 break;
752 #ifdef DEBUG
753 puts("End icon move");
754 #endif