1 /* appicon.c- icon for applications (not mini-window)
3 * Window Maker window manager
5 * Copyright (c) 1997, 1998 Alfredo K. Kojima
6 * Copyright (c) 1998 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,
27 #include <X11/Xutil.h>
31 #include "WindowMaker.h"
41 #include "workspace.h"
42 #include "superfluous.h"
51 #include <WINGs/WINGsP.h>
55 * icon_file for the dock is got from the preferences file by
56 * using the classname/instancename
59 /**** Global variables ****/
60 extern Cursor wCursor
[WCUR_LAST
];
61 extern WPreferences wPreferences
;
63 #define MOD_MASK wPreferences.modifier_mask
65 void appIconMouseDown(WObjDescriptor
*desc
, XEvent
*event
);
66 static void iconDblClick(WObjDescriptor
*desc
, XEvent
*event
);
67 static void iconExpose(WObjDescriptor
*desc
, XEvent
*event
);
72 wAppIconCreateForDock(WScreen
*scr
, char *command
, char *wm_instance
,
73 char *wm_class
, int tile
)
78 dicon
= wmalloc(sizeof(WAppIcon
));
80 memset(dicon
, 0, sizeof(WAppIcon
));
85 dicon
->next
= scr
->app_icon_list
;
86 if (scr
->app_icon_list
) {
87 scr
->app_icon_list
->prev
= dicon
;
89 scr
->app_icon_list
= dicon
;
92 dicon
->command
= wstrdup(command
);
95 dicon
->wm_class
= wstrdup(wm_class
);
97 dicon
->wm_instance
= wstrdup(wm_instance
);
99 path
= wDefaultGetIconFile(scr
, wm_instance
, wm_class
, True
);
100 if (!path
&& command
) {
101 wApplicationExtractDirPackIcon(scr
, command
, wm_instance
, wm_class
);
103 path
= wDefaultGetIconFile(scr
, wm_instance
, wm_class
, False
);
107 path
= FindImage(wPreferences
.icon_path
, path
);
109 dicon
->icon
= wIconCreateWithIconFile(scr
, path
, tile
);
113 wXDNDMakeAwareness(dicon
->icon
->core
->window
);
116 #ifdef DEMATERIALIZE_ICON
118 XSetWindowAttributes attribs
;
119 attribs
.save_under
= True
;
120 XChangeWindowAttributes(dpy
, dicon
->icon
->core
->window
,
121 CWSaveUnder
, &attribs
);
125 /* will be overriden by dock */
126 dicon
->icon
->core
->descriptor
.handle_mousedown
= appIconMouseDown
;
127 dicon
->icon
->core
->descriptor
.handle_expose
= iconExpose
;
128 dicon
->icon
->core
->descriptor
.parent_type
= WCLASS_APPICON
;
129 dicon
->icon
->core
->descriptor
.parent
= dicon
;
130 AddToStackList(dicon
->icon
->core
);
138 wAppIconCreate(WWindow
*leader_win
)
141 WScreen
*scr
= leader_win
->screen_ptr
;
143 aicon
= wmalloc(sizeof(WAppIcon
));
145 memset(aicon
, 0, sizeof(WAppIcon
));
151 aicon
->next
= scr
->app_icon_list
;
152 if (scr
->app_icon_list
) {
153 scr
->app_icon_list
->prev
= aicon
;
155 scr
->app_icon_list
= aicon
;
157 if (leader_win
->wm_class
)
158 aicon
->wm_class
= wstrdup(leader_win
->wm_class
);
159 if (leader_win
->wm_instance
)
160 aicon
->wm_instance
= wstrdup(leader_win
->wm_instance
);
162 aicon
->icon
= wIconCreate(leader_win
);
163 #ifdef DEMATERIALIZE_ICON
165 XSetWindowAttributes attribs
;
166 attribs
.save_under
= True
;
167 XChangeWindowAttributes(dpy
, aicon
->icon
->core
->window
,
168 CWSaveUnder
, &attribs
);
172 wXDNDMakeAwareness(aicon
->icon
->core
->window
);
175 /* will be overriden if docked */
176 aicon
->icon
->core
->descriptor
.handle_mousedown
= appIconMouseDown
;
177 aicon
->icon
->core
->descriptor
.handle_expose
= iconExpose
;
178 aicon
->icon
->core
->descriptor
.parent_type
= WCLASS_APPICON
;
179 aicon
->icon
->core
->descriptor
.parent
= aicon
;
180 AddToStackList(aicon
->icon
->core
);
181 aicon
->icon
->show_title
= 0;
182 wIconUpdate(aicon
->icon
);
189 wAppIconDestroy(WAppIcon
*aicon
)
191 WScreen
*scr
= aicon
->icon
->core
->screen_ptr
;
193 RemoveFromStackList(aicon
->icon
->core
);
194 wIconDestroy(aicon
->icon
);
196 wfree(aicon
->command
);
198 if (aicon
->dnd_command
)
199 wfree(aicon
->dnd_command
);
201 if (aicon
->wm_instance
)
202 wfree(aicon
->wm_instance
);
204 wfree(aicon
->wm_class
);
206 if (aicon
== scr
->app_icon_list
) {
208 aicon
->next
->prev
= NULL
;
209 scr
->app_icon_list
= aicon
->next
;
213 aicon
->next
->prev
= aicon
->prev
;
215 aicon
->prev
->next
= aicon
->next
;
218 aicon
->destroyed
= 1;
226 drawCorner(WIcon
*icon
, WWindow
*wwin
, int active
)
228 WScreen
*scr
= wwin
->screen_ptr
;
239 gc
=scr
->focused_texture
->any
.gc
;
241 gc
=scr
->unfocused_texture
->any
.gc
;
243 XFillPolygon(dpy
, icon
->core
->window
, gc
, points
, 3,
244 Convex
, CoordModeOrigin
);
246 #endif /* NEWAPPICON */
250 drawCorner(WIcon
*icon
)
252 WScreen
*scr
= icon
->core
->screen_ptr
;
261 XFillPolygon(dpy
, icon
->core
->window
, scr
->icon_title_texture
->normal_gc
,
262 points
, 3, Convex
, CoordModeOrigin
);
263 XDrawLine(dpy
, icon
->core
->window
, scr
->icon_title_texture
->light_gc
,
265 XDrawLine(dpy
, icon
->core
->window
, scr
->icon_title_texture
->light_gc
,
267 /* drawing the second line gives a weird concave look. -Dan */
269 XDrawLine(dpy
, icon
->core
->window
, scr
->icon_title_texture
->light_gc
,
271 XDrawLine(dpy
, icon
->core
->window
, scr
->icon_title_texture
->light_gc
,
278 wAppIconMove(WAppIcon
*aicon
, int x
, int y
)
283 app
= wApplicationOf(aicon
->icon
->owner
->main_window
);
285 if (!WFLAGP(app
->main_window_desc
, collapse_appicons
)) {
286 XMoveWindow(dpy
, aicon
->icon
->core
->window
, x
, y
);
290 tmp
= aicon
->icon
->core
->screen_ptr
->app_icon_list
;
292 /* move all icons of the same class/name to the same pos */
294 if (strcmp(tmp
->wm_class
, aicon
->wm_class
) == 0 &&
295 strcmp(tmp
->wm_instance
, aicon
->wm_instance
) == 0 &&
297 XMoveWindow(dpy
, tmp
->icon
->core
->window
, x
, y
);
309 updateDockNumbers(WScreen
*scr
)
314 XGCValues my_gc_values
;
315 unsigned long my_v_mask
= (GCForeground
);
316 WAppIcon
*dicon
= scr
->dock
->icon_array
[0];
318 my_gc_values
.foreground
= scr
->white_pixel
;
319 numbers_gc
= XCreateGC(dpy
, dicon
->icon
->core
->window
,
320 my_v_mask
, &my_gc_values
);
322 ws_numbers
= wmalloc(20);
323 snprintf(ws_numbers
, 20, "%i [ %i ]", scr
->current_workspace
+1,
324 ((scr
->current_workspace
/10)+1));
325 length
= strlen(ws_numbers
);
327 XClearArea(dpy
, dicon
->icon
->core
->window
, 2, 2, 50,
328 WMFontHeight(scr
->icon_title_font
)+1, False
);
330 XSetForeground(dpy
, numbers_gc
, scr
->black_pixel
);
331 WMDrawString(scr
->wmscreen
, dicon
->icon
->core
->window
, numbers_gc
,
332 scr
->icon_title_font
, 4, 3, ws_numbers
, length
);
334 XSetForeground(dpy
, numbers_gc
, scr
->white_pixel
);
335 WMDrawString(scr
->wmscreen
, dicon
->icon
->core
->window
, numbers_gc
,
336 scr
->icon_title_font
, 3, 2, ws_numbers
, length
);
338 XFreeGC(dpy
, numbers_gc
);
341 #endif /* WS_INDICATOR */
346 wAppIconNextSibling(WAppIcon
*icon
)
351 app
= wApplicationOf(icon
->icon
->owner
->main_window
);
353 if (!WFLAGP(app
->main_window_desc
, collapse_appicons
)) {
359 if (strcmp(tmp
->wm_class
, icon
->wm_class
) == 0
360 && strcmp(tmp
->wm_instance
, icon
->wm_instance
) == 0
367 tmp
= icon
->icon
->core
->screen_ptr
->app_icon_list
;
368 while (tmp
&& tmp
!= icon
) {
369 if (strcmp(tmp
->wm_class
, icon
->wm_class
) == 0
370 && strcmp(tmp
->wm_instance
, icon
->wm_instance
) == 0
382 wAppIconIsFirstInstance(WAppIcon
*icon
)
384 WAppIcon
*list
= icon
->icon
->core
->screen_ptr
->app_icon_list
;
387 if (!WFLAGP(icon
->icon
->owner
, collapse_appicons
))
394 if (strcmp(icon
->wm_instance
,
395 list
->wm_instance
) == 0
397 strcmp(icon
->wm_class
,
405 puts("OH SHIT!?!?!? HOW THE FUCK DID WE GET HERE!?!?!?!?!");
413 wAppIconPaint(WAppIcon
*aicon
)
416 WScreen
*scr
= aicon
->icon
->core
->screen_ptr
;
419 if (aicon
->icon
->owner
)
420 wapp
= wApplicationOf(aicon
->icon
->owner
->main_window
);
424 wIconPaint(aicon
->icon
);
428 if (aicon
->docked
&& scr
->dock
&& scr
->dock
==aicon
->dock
&&
430 updateDockNumbers(scr
);
432 if (scr
->dock_dots
&& aicon
->docked
&& !aicon
->running
433 && aicon
->command
!=NULL
) {
434 XSetClipMask(dpy
, scr
->copy_gc
, scr
->dock_dots
->mask
);
435 XSetClipOrigin(dpy
, scr
->copy_gc
, 0, 0);
436 XCopyArea(dpy
, scr
->dock_dots
->image
, aicon
->icon
->core
->window
,
437 scr
->copy_gc
, 0, 0, scr
->dock_dots
->width
,
438 scr
->dock_dots
->height
, 0, 0);
442 if (wapp
&& wapp
->flags
.hidden
) {
443 XSetClipMask(dpy
, scr
->copy_gc
, scr
->dock_dots
->mask
);
444 XSetClipOrigin(dpy
, scr
->copy_gc
, 0, 0);
445 XCopyArea(dpy
, scr
->dock_dots
->image
,
446 aicon
->icon
->core
->window
,
447 scr
->copy_gc
, 0, 0, 7,
448 scr
->dock_dots
->height
, 0, 0);
450 #endif /* HIDDENDOT */
453 index
= wApplicationIndexOfGroup(wapp
);
460 snprintf(buf
, sizeof(buf
), "%i", index
);
462 WMDrawString(scr
->wmscreen
, aicon
->icon
->core
->window
,
463 scr
->clip_title_gc
, scr
->title_font
,
464 3, 3, buf
, strlen(buf
));
468 if (aicon
->omnipresent
)
469 drawCorner(aicon
->icon
);
471 XSetClipMask(dpy
, scr
->copy_gc
, None
);
472 if (aicon
->launching
) {
473 XFillRectangle(dpy
, aicon
->icon
->core
->window
, scr
->stipple_gc
,
474 0, 0, wPreferences
.icon_size
, wPreferences
.icon_size
);
480 #define canBeDocked(wwin) ((wwin) && ((wwin)->wm_class||(wwin)->wm_instance))
485 hideCallback(WMenu
*menu
, WMenuEntry
*entry
)
487 WApplication
*wapp
= (WApplication
*)entry
->clientdata
;
489 if (wapp
->flags
.hidden
) {
490 wWorkspaceChange(menu
->menu
->screen_ptr
, wapp
->last_workspace
);
491 wUnhideApplication(wapp
, False
, False
);
493 wHideApplication(wapp
);
499 unhideHereCallback(WMenu
*menu
, WMenuEntry
*entry
)
501 WApplication
*wapp
= (WApplication
*)entry
->clientdata
;
503 wUnhideApplication(wapp
, False
, True
);
508 collapseCallback(WMenu
*menu
, WMenuEntry
*entry
)
510 WApplication
*wapp
= (WApplication
*)entry
->clientdata
;
512 wApplicationSetCollapse(wapp
,
513 !WFLAGP(wapp
->main_window_desc
, collapse_appicons
));
518 setIconCallback(WMenu
*menu
, WMenuEntry
*entry
)
520 WAppIcon
*icon
= ((WApplication
*)entry
->clientdata
)->app_icon
;
530 scr
= icon
->icon
->core
->screen_ptr
;
534 result
= wIconChooserDialog(scr
, &file
, icon
->wm_instance
, icon
->wm_class
);
536 if (result
&& !icon
->destroyed
) {
541 if (!wIconChangeImageFile(icon
->icon
, file
)) {
542 wMessageDialog(scr
, _("Error"),
543 _("Could not open specified icon file"),
544 _("OK"), NULL
, NULL
);
546 wDefaultChangeIcon(scr
, icon
->wm_instance
, icon
->wm_class
, file
);
558 killCallback(WMenu
*menu
, WMenuEntry
*entry
)
560 WApplication
*wapp
= (WApplication
*)entry
->clientdata
;
563 if (!WCHECK_STATE(WSTATE_NORMAL
))
566 WCHANGE_STATE(WSTATE_MODAL
);
568 assert(entry
->clientdata
!=NULL
);
570 buffer
= wstrconcat(wapp
->app_icon
? wapp
->app_icon
->wm_class
: NULL
,
571 _(" will be forcibly closed.\n"
572 "Any unsaved changes will be lost.\n"
575 wretain(wapp
->main_window_desc
);
576 if (wPreferences
.dont_confirm_kill
577 || wMessageDialog(menu
->frame
->screen_ptr
, _("Kill Application"),
578 buffer
, _("Yes"), _("No"), NULL
)==WAPRDefault
) {
579 if (!wapp
->main_window_desc
->flags
.destroyed
)
580 wClientKill(wapp
->main_window_desc
);
582 wrelease(wapp
->main_window_desc
);
586 WCHANGE_STATE(WSTATE_NORMAL
);
591 createApplicationMenu(WScreen
*scr
)
595 menu
= wMenuCreate(scr
, NULL
, False
);
596 wMenuAddCallback(menu
, _("Unhide Here"), unhideHereCallback
, NULL
);
597 wMenuAddCallback(menu
, _("Hide"), hideCallback
, NULL
);
598 wMenuAddCallback(menu
, _("Collapse"), collapseCallback
, NULL
);
599 wMenuAddCallback(menu
, _("Set Icon..."), setIconCallback
, NULL
);
600 wMenuAddCallback(menu
, _("Kill"), killCallback
, NULL
);
607 openApplicationMenu(WApplication
*wapp
, int x
, int y
)
610 WScreen
*scr
= wapp
->main_window_desc
->screen_ptr
;
613 if (!scr
->icon_menu
) {
614 scr
->icon_menu
= createApplicationMenu(scr
);
615 wfree(scr
->icon_menu
->entries
[1]->text
);
618 menu
= scr
->icon_menu
;
620 if (wapp
->flags
.hidden
) {
621 menu
->entries
[1]->text
= _("Unhide");
623 menu
->entries
[1]->text
= _("Hide");
626 if (WFLAGP(wapp
->main_window_desc
, collapse_appicons
)) {
627 menu
->entries
[2]->text
= _("Uncollapse");
629 menu
->entries
[2]->text
= _("Collapse");
632 menu
->flags
.realized
= 0;
635 x
-= menu
->frame
->core
->width
/2;
636 if (x
+ menu
->frame
->core
->width
> scr
->scr_width
)
637 x
= scr
->scr_width
- menu
->frame
->core
->width
;
641 /* set client data */
642 for (i
= 0; i
< menu
->entry_no
; i
++) {
643 menu
->entries
[i
]->clientdata
= wapp
;
645 wMenuMapAt(menu
, x
, y
, False
);
649 /******************************************************************/
652 iconExpose(WObjDescriptor
*desc
, XEvent
*event
)
654 wAppIconPaint(desc
->parent
);
659 iconDblClick(WObjDescriptor
*desc
, XEvent
*event
)
661 WAppIcon
*aicon
= desc
->parent
;
663 WScreen
*scr
= aicon
->icon
->core
->screen_ptr
;
666 assert(aicon
->icon
->owner
!=NULL
);
668 wapp
= wApplicationOf(aicon
->icon
->owner
->main_window
);
671 wwarning("could not find application descriptor for app icon!!");
676 unhideHere
= (event
->xbutton
.state
& ShiftMask
);
678 /* go to the last workspace that the user worked on the app */
679 if (!unhideHere
&& wapp
->last_workspace
!= scr
->current_workspace
)
680 wWorkspaceChange(scr
, wapp
->last_workspace
);
682 wUnhideApplication(wapp
, event
->xbutton
.button
==Button2
, unhideHere
);
684 if (event
->xbutton
.state
& MOD_MASK
) {
685 wHideOtherApplications(aicon
->icon
->owner
);
692 appIconMouseDown(WObjDescriptor
*desc
, XEvent
*event
)
694 WAppIcon
*aicon
= desc
->parent
;
695 WIcon
*icon
= aicon
->icon
;
697 int x
=aicon
->x_pos
, y
=aicon
->y_pos
;
698 int dx
=event
->xbutton
.x
, dy
=event
->xbutton
.y
;
701 int superfluous
= wPreferences
.superfluous
; /* we catch it to avoid problems */
702 WScreen
*scr
= icon
->core
->screen_ptr
;
703 WWorkspace
*workspace
= scr
->workspaces
[scr
->current_workspace
];
704 int shad_x
= 0, shad_y
= 0, docking
=0, dockable
, collapsed
= 0;
706 int clickButton
= event
->xbutton
.button
;
709 Bool movingSingle
= False
;
713 if (aicon
->editing
|| WCHECK_STATE(WSTATE_MODAL
))
716 if (event
->xbutton
.button
== Button1
&& IsDoubleClick(scr
, event
)) {
717 iconDblClick(desc
, event
);
721 if (event
->xbutton
.button
== Button3
) {
722 WObjDescriptor
*desc
;
723 WApplication
*wapp
= wApplicationOf(aicon
->icon
->owner
->main_window
);
728 if (event
->xbutton
.send_event
&&
729 XGrabPointer(dpy
, aicon
->icon
->core
->window
, True
, ButtonMotionMask
730 |ButtonReleaseMask
|ButtonPressMask
, GrabModeAsync
,
731 GrabModeAsync
, None
, None
, CurrentTime
) !=GrabSuccess
) {
732 wwarning("pointer grab failed for appicon menu");
736 openApplicationMenu(wapp
, event
->xbutton
.x_root
,
737 event
->xbutton
.y_root
);
739 /* allow drag select of menu */
740 desc
= &scr
->icon_menu
->menu
->descriptor
;
741 event
->xbutton
.send_event
= True
;
742 (*desc
->handle_mousedown
)(desc
, event
);
749 if (event
->xbutton
.state
& MOD_MASK
)
750 wLowerFrame(icon
->core
);
752 wRaiseFrame(icon
->core
);
755 if (clickButton
== Button2
) {
756 WAppIcon
*next
= wAppIconNextSibling(aicon
);
759 wRaiseFrame(next
->icon
->core
);
764 if (XGrabPointer(dpy
, icon
->core
->window
, True
, ButtonMotionMask
765 |ButtonReleaseMask
|ButtonPressMask
, GrabModeAsync
,
766 GrabModeAsync
, None
, None
, CurrentTime
) !=GrabSuccess
) {
767 wwarning("pointer grab failed for appicon move");
770 if (wPreferences
.flags
.nodock
&& wPreferences
.flags
.noclip
)
773 dockable
= canBeDocked(icon
->owner
);
775 wins
[0] = icon
->core
->window
;
776 wins
[1] = scr
->dock_shadow
;
777 XRestackWindows(dpy
, wins
, 2);
779 if (icon
->pixmap
!=None
)
780 ghost
= MakeGhostIcon(scr
, icon
->pixmap
);
782 ghost
= MakeGhostIcon(scr
, icon
->core
->window
);
783 XSetWindowBackgroundPixmap(dpy
, scr
->dock_shadow
,
785 XClearWindow(dpy
, scr
->dock_shadow
);
789 WMMaskEvent(dpy
, PointerMotionMask
|ButtonReleaseMask
|ButtonPressMask
790 |ButtonMotionMask
|ExposureMask
, &ev
);
798 if (abs(dx
-ev
.xmotion
.x
)>=MOVE_THRESHOLD
799 || abs(dy
-ev
.xmotion
.y
)>=MOVE_THRESHOLD
) {
800 XChangeActivePointerGrab(dpy
, ButtonMotionMask
801 |ButtonReleaseMask
|ButtonPressMask
,
802 wCursor
[WCUR_MOVE
], CurrentTime
);
808 x
= ev
.xmotion
.x_root
- dx
;
809 y
= ev
.xmotion
.y_root
- dy
;
812 XMoveWindow(dpy
, icon
->core
->window
, x
, y
);
814 wAppIconMove(aicon
, x
, y
);
818 if (scr
->dock
&& wDockSnapIcon(scr
->dock
, aicon
, x
, y
,
820 shad_x
= scr
->dock
->x_pos
+ ix
*wPreferences
.icon_size
;
821 shad_y
= scr
->dock
->y_pos
+ iy
*wPreferences
.icon_size
;
823 if (scr
->last_dock
!= scr
->dock
&& collapsed
) {
824 scr
->last_dock
->collapsed
= 1;
825 wDockHideIcons(scr
->last_dock
);
828 if (!collapsed
&& (collapsed
= scr
->dock
->collapsed
)) {
829 scr
->dock
->collapsed
= 0;
830 wDockShowIcons(scr
->dock
);
833 if (scr
->dock
->auto_raise_lower
)
834 wDockRaise(scr
->dock
);
836 scr
->last_dock
= scr
->dock
;
838 XMoveWindow(dpy
, scr
->dock_shadow
, shad_x
, shad_y
);
840 XMapWindow(dpy
, scr
->dock_shadow
);
843 } else if (workspace
->clip
&&
844 wDockSnapIcon(workspace
->clip
, aicon
, x
, y
,
846 shad_x
= workspace
->clip
->x_pos
+ ix
*wPreferences
.icon_size
;
847 shad_y
= workspace
->clip
->y_pos
+ iy
*wPreferences
.icon_size
;
849 if (scr
->last_dock
!= workspace
->clip
&& collapsed
) {
850 scr
->last_dock
->collapsed
= 1;
851 wDockHideIcons(scr
->last_dock
);
854 if (!collapsed
&& (collapsed
= workspace
->clip
->collapsed
)) {
855 workspace
->clip
->collapsed
= 0;
856 wDockShowIcons(workspace
->clip
);
859 if (workspace
->clip
->auto_raise_lower
)
860 wDockRaise(workspace
->clip
);
862 scr
->last_dock
= workspace
->clip
;
864 XMoveWindow(dpy
, scr
->dock_shadow
, shad_x
, shad_y
);
866 XMapWindow(dpy
, scr
->dock_shadow
);
869 } else if (docking
) {
870 XUnmapWindow(dpy
, scr
->dock_shadow
);
881 if (ev
.xbutton
.button
!= clickButton
)
883 XUngrabPointer(dpy
, CurrentTime
);
888 /* icon is trying to be docked */
889 SlideWindow(icon
->core
->window
, x
, y
, shad_x
, shad_y
);
890 XUnmapWindow(dpy
, scr
->dock_shadow
);
891 docked
= wDockAttachIcon(scr
->last_dock
, aicon
, ix
, iy
);
892 if (scr
->last_dock
->auto_collapse
) {
895 if (workspace
->clip
&&
896 workspace
->clip
!= scr
->last_dock
&&
897 workspace
->clip
->auto_raise_lower
)
898 wDockLower(workspace
->clip
);
901 /* If icon could not be docked, slide it back to the old
903 SlideWindow(icon
->core
->window
, x
, y
, oldX
, oldY
);
905 WAppIcon
*nextIcon
= wAppIconNextSibling(aicon
);
908 /* move the next instance back to the old position */
909 SlideWindow(nextIcon
->icon
->core
->window
, x
, y
,
911 wAppIconMove(nextIcon
, oldX
, oldY
);
915 wSoundPlay(WSOUND_DOCK
);
918 /* move back to its place */
919 SlideWindow(icon
->core
->window
, x
, y
, oldX
, oldY
);
920 wAppIconMove(aicon
, oldX
, oldY
);
922 XMoveWindow(dpy
, icon
->core
->window
, x
, y
);
926 if (workspace
->clip
&& workspace
->clip
->auto_raise_lower
)
927 wDockLower(workspace
->clip
);
930 scr
->last_dock
->collapsed
= 1;
931 wDockHideIcons(scr
->last_dock
);
936 XFreePixmap(dpy
, ghost
);
937 XSetWindowBackground(dpy
, scr
->dock_shadow
, scr
->white_pixel
);
940 if (wPreferences
.auto_arrange_icons
)
941 wArrangeIcons(scr
, True
);
948 puts("End icon move");