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"
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
);
115 #ifdef REDUCE_APPICONS
118 #ifdef DEMATERIALIZE_ICON
120 XSetWindowAttributes attribs
;
121 attribs
.save_under
= True
;
122 XChangeWindowAttributes(dpy
, dicon
->icon
->core
->window
,
123 CWSaveUnder
, &attribs
);
127 /* will be overriden by dock */
128 dicon
->icon
->core
->descriptor
.handle_mousedown
= appIconMouseDown
;
129 dicon
->icon
->core
->descriptor
.handle_expose
= iconExpose
;
130 dicon
->icon
->core
->descriptor
.parent_type
= WCLASS_APPICON
;
131 dicon
->icon
->core
->descriptor
.parent
= dicon
;
132 AddToStackList(dicon
->icon
->core
);
140 wAppIconCreate(WWindow
*leader_win
)
143 #ifdef REDUCE_APPICONS
145 WAppIconAppList
*applist
;
146 char *tinstance
, *tclass
;
148 WScreen
*scr
= leader_win
->screen_ptr
;
150 aicon
= wmalloc(sizeof(WAppIcon
));
152 memset(aicon
, 0, sizeof(WAppIcon
));
153 #ifdef REDUCE_APPICONS
154 applist
= wmalloc(sizeof(WAppIconAppList
));
155 memset(applist
, 0, sizeof(WAppIconAppList
));
156 applist
->wapp
= wApplicationOf(leader_win
->main_window
);
157 aicon
->applist
= applist
;
158 if (applist
->wapp
== NULL
) {
159 /* Something's wrong. wApplicationOf() should always return a
160 * valid structure. Rather than violate assumptions, bail. -cls
172 aicon
->next
= scr
->app_icon_list
;
173 if (scr
->app_icon_list
) {
174 #ifndef REDUCE_APPICONS
175 scr
->app_icon_list
->prev
= aicon
;
177 /* If we aren't going to have a match, jump straight to new appicon */
178 if (leader_win
->wm_class
== NULL
|| leader_win
->wm_class
== NULL
)
181 atmp
= scr
->app_icon_list
;
183 while (atmp
!= NULL
) {
184 if ((tinstance
= atmp
->wm_instance
) == NULL
)
186 if ((tclass
= atmp
->wm_class
) == NULL
)
188 if ((strcmp(leader_win
->wm_class
, tclass
) == 0) &&
189 (strcmp(leader_win
->wm_instance
, tinstance
) == 0))
191 /* We have a winner */
194 applist
->next
= atmp
->applist
;
196 atmp
->applist
->prev
= applist
;
197 atmp
->applist
= applist
;
200 wDockSimulateLaunch(atmp
->dock
, atmp
);
208 scr
->app_icon_list
->prev
= aicon
;
210 #endif /* REDUCE_APPICONS */
212 scr
->app_icon_list
= aicon
;
214 if (leader_win
->wm_class
)
215 aicon
->wm_class
= wstrdup(leader_win
->wm_class
);
216 if (leader_win
->wm_instance
)
217 aicon
->wm_instance
= wstrdup(leader_win
->wm_instance
);
218 #ifdef REDUCE_APPICONS
222 aicon
->icon
= wIconCreate(leader_win
);
223 #ifdef DEMATERIALIZE_ICON
225 XSetWindowAttributes attribs
;
226 attribs
.save_under
= True
;
227 XChangeWindowAttributes(dpy
, aicon
->icon
->core
->window
,
228 CWSaveUnder
, &attribs
);
232 wXDNDMakeAwareness(aicon
->icon
->core
->window
);
235 /* will be overriden if docked */
236 aicon
->icon
->core
->descriptor
.handle_mousedown
= appIconMouseDown
;
237 aicon
->icon
->core
->descriptor
.handle_expose
= iconExpose
;
238 aicon
->icon
->core
->descriptor
.parent_type
= WCLASS_APPICON
;
239 aicon
->icon
->core
->descriptor
.parent
= aicon
;
240 AddToStackList(aicon
->icon
->core
);
241 aicon
->icon
->show_title
= 0;
242 wIconUpdate(aicon
->icon
);
249 wAppIconDestroy(WAppIcon
*aicon
)
251 WScreen
*scr
= aicon
->icon
->core
->screen_ptr
;
252 #ifdef REDUCE_APPICONS
253 WAppIconAppList
*aptmp
;
256 RemoveFromStackList(aicon
->icon
->core
);
257 wIconDestroy(aicon
->icon
);
259 free(aicon
->command
);
261 if (aicon
->dnd_command
)
262 free(aicon
->dnd_command
);
264 if (aicon
->wm_instance
)
265 free(aicon
->wm_instance
);
267 free(aicon
->wm_class
);
268 #ifdef REDUCE_APPICONS
269 /* There should never be a list but just in case */
270 if (aicon
->applist
!= NULL
) {
271 aptmp
= aicon
->applist
;
272 while (aptmp
->next
) {
280 if (aicon
== scr
->app_icon_list
) {
282 aicon
->next
->prev
= NULL
;
283 scr
->app_icon_list
= aicon
->next
;
287 aicon
->next
->prev
= aicon
->prev
;
289 aicon
->prev
->next
= aicon
->next
;
292 aicon
->destroyed
= 1;
300 drawCorner(WIcon
*icon
, WWindow
*wwin
, int active
)
302 WScreen
*scr
= wwin
->screen_ptr
;
313 gc
=scr
->focused_texture
->any
.gc
;
315 gc
=scr
->unfocused_texture
->any
.gc
;
317 XFillPolygon(dpy
, icon
->core
->window
, gc
, points
, 3,
318 Convex
, CoordModeOrigin
);
320 #endif /* NEWAPPICON */
324 drawCorner(WIcon
*icon
)
326 WScreen
*scr
= icon
->core
->screen_ptr
;
335 XFillPolygon(dpy
, icon
->core
->window
, scr
->icon_title_texture
->normal_gc
,
336 points
, 3, Convex
, CoordModeOrigin
);
337 XDrawLine(dpy
, icon
->core
->window
, scr
->icon_title_texture
->light_gc
,
339 XDrawLine(dpy
, icon
->core
->window
, scr
->icon_title_texture
->light_gc
,
341 /* drawing the second line gives a weird concave look. -Dan */
343 XDrawLine(dpy
, icon
->core
->window
, scr
->icon_title_texture
->light_gc
,
345 XDrawLine(dpy
, icon
->core
->window
, scr
->icon_title_texture
->light_gc
,
352 wAppIconMove(WAppIcon
*aicon
, int x
, int y
)
354 XMoveWindow(dpy
, aicon
->icon
->core
->window
, x
, y
);
362 updateDockNumbers(WScreen
*scr
)
367 XGCValues my_gc_values
;
368 unsigned long my_v_mask
= (GCForeground
);
369 WAppIcon
*dicon
= scr
->dock
->icon_array
[0];
371 my_gc_values
.foreground
= scr
->white_pixel
;
372 numbers_gc
= XCreateGC(dpy
, dicon
->icon
->core
->window
,
373 my_v_mask
, &my_gc_values
);
375 ws_numbers
= malloc(20);
376 sprintf(ws_numbers
, "%i [ %i ]", scr
->current_workspace
+1,
377 ((scr
->current_workspace
/10)+1));
378 length
= strlen(ws_numbers
);
380 XClearArea(dpy
, dicon
->icon
->core
->window
, 2, 2, 50,
381 WMFontHeight(scr
->icon_title_font
)+1, False
);
383 XSetForeground(dpy
, numbers_gc
, scr
->black_pixel
);
384 WMDrawString(scr
->wmscreen
, dicon
->icon
->core
->window
, numbers_gc
,
385 scr
->icon_title_font
, 4, 3, ws_numbers
, length
);
387 XSetForeground(dpy
, numbers_gc
, scr
->white_pixel
);
388 WMDrawString(scr
->wmscreen
, dicon
->icon
->core
->window
, numbers_gc
,
389 scr
->icon_title_font
, 3, 2, ws_numbers
, length
);
391 XFreeGC(dpy
, numbers_gc
);
394 #endif /* WS_INDICATOR */
398 wAppIconPaint(WAppIcon
*aicon
)
400 WScreen
*scr
= aicon
->icon
->core
->screen_ptr
;
402 wIconPaint(aicon
->icon
);
406 if (aicon
->docked
&& scr
->dock
&& scr
->dock
==aicon
->dock
&&
408 updateDockNumbers(scr
);
410 if (scr
->dock_dots
&& aicon
->docked
&& !aicon
->running
411 && aicon
->command
!=NULL
) {
412 XSetClipMask(dpy
, scr
->copy_gc
, scr
->dock_dots
->mask
);
413 XSetClipOrigin(dpy
, scr
->copy_gc
, 0, 0);
414 XCopyArea(dpy
, scr
->dock_dots
->image
, aicon
->icon
->core
->window
,
415 scr
->copy_gc
, 0, 0, scr
->dock_dots
->width
,
416 scr
->dock_dots
->height
, 0, 0);
422 wapp
= wApplicationOf(aicon
->main_window
);
423 if (wapp
&& wapp
->flags
.hidden
) {
424 XSetClipMask(dpy
, scr
->copy_gc
, scr
->dock_dots
->mask
);
425 XSetClipOrigin(dpy
, scr
->copy_gc
, 0, 0);
426 XCopyArea(dpy
, scr
->dock_dots
->image
,
427 aicon
->icon
->core
->window
,
428 scr
->copy_gc
, 0, 0, 7,
429 scr
->dock_dots
->height
, 0, 0);
432 #endif /* HIDDENDOT */
434 if (aicon
->omnipresent
)
435 drawCorner(aicon
->icon
);
437 XSetClipMask(dpy
, scr
->copy_gc
, None
);
438 if (aicon
->launching
) {
439 XFillRectangle(dpy
, aicon
->icon
->core
->window
, scr
->stipple_gc
,
440 0, 0, wPreferences
.icon_size
, wPreferences
.icon_size
);
446 #define canBeDocked(wwin) ((wwin) && ((wwin)->wm_class||(wwin)->wm_instance))
448 #ifdef REDUCE_APPICONS
450 wAppIconReduceAppCount(WApplication
*wapp
)
452 WAppIconAppList
*applist
;
457 if (wapp
->app_icon
== NULL
)
460 /* If given a main window, check the applist
461 * and remove the if it exists
463 applist
= wapp
->app_icon
->applist
;
464 while (applist
!= NULL
) {
465 if (applist
->wapp
== wapp
) {
466 /* If this app owns the appicon, change the appicon's
467 * owner to the next app in the list or NULL
469 if (wapp
->app_icon
->icon
->owner
470 == applist
->wapp
->main_window_desc
) {
472 wapp
->app_icon
->icon
->owner
= applist
->next
->wapp
->main_window_desc
;
473 } else if (applist
->prev
) {
474 wapp
->app_icon
->icon
->owner
= applist
->prev
->wapp
->main_window_desc
;
476 wapp
->app_icon
->icon
->owner
= NULL
;
480 applist
->prev
->next
= applist
->next
;
483 applist
->next
->prev
= applist
->prev
;
485 if (applist
== wapp
->app_icon
->applist
)
486 wapp
->app_icon
->applist
= applist
->next
;
490 if (wapp
->app_icon
->applist
!= NULL
)
491 wapp
->app_icon
->main_window
= wapp
->app_icon
->applist
->wapp
->main_window
;
493 return (--wapp
->app_icon
->num_apps
);
495 applist
= applist
->next
;
497 return (--wapp
->app_icon
->num_apps
);
503 hideCallback(WMenu
*menu
, WMenuEntry
*entry
)
505 WApplication
*wapp
= (WApplication
*)entry
->clientdata
;
507 if (wapp
->flags
.hidden
) {
508 wWorkspaceChange(menu
->menu
->screen_ptr
, wapp
->last_workspace
);
509 wUnhideApplication(wapp
, False
, False
);
511 wHideApplication(wapp
);
517 unhideHereCallback(WMenu
*menu
, WMenuEntry
*entry
)
519 WApplication
*wapp
= (WApplication
*)entry
->clientdata
;
521 wUnhideApplication(wapp
, False
, True
);
526 setIconCallback(WMenu
*menu
, WMenuEntry
*entry
)
528 WAppIcon
*icon
= ((WApplication
*)entry
->clientdata
)->app_icon
;
538 scr
= icon
->icon
->core
->screen_ptr
;
542 result
= wIconChooserDialog(scr
, &file
, icon
->wm_instance
, icon
->wm_class
);
544 if (result
&& !icon
->destroyed
) {
549 if (!wIconChangeImageFile(icon
->icon
, file
)) {
550 wMessageDialog(scr
, _("Error"),
551 _("Could not open specified icon file"),
552 _("OK"), NULL
, NULL
);
554 wDefaultChangeIcon(scr
, icon
->wm_instance
, icon
->wm_class
, file
);
566 killCallback(WMenu
*menu
, WMenuEntry
*entry
)
568 WApplication
*wapp
= (WApplication
*)entry
->clientdata
;
571 if (!WCHECK_STATE(WSTATE_NORMAL
))
574 WCHANGE_STATE(WSTATE_MODAL
);
576 assert(entry
->clientdata
!=NULL
);
578 buffer
= wstrappend(wapp
->app_icon
? wapp
->app_icon
->wm_class
: NULL
,
579 _(" will be forcibly closed.\n"
580 "Any unsaved changes will be lost.\n"
583 wretain(wapp
->main_window_desc
);
584 if (wPreferences
.dont_confirm_kill
585 || wMessageDialog(menu
->frame
->screen_ptr
, _("Kill Application"),
586 buffer
, _("Yes"), _("No"), NULL
)==WAPRDefault
) {
587 if (!wapp
->main_window_desc
->flags
.destroyed
)
588 wClientKill(wapp
->main_window_desc
);
590 wrelease(wapp
->main_window_desc
);
594 WCHANGE_STATE(WSTATE_NORMAL
);
599 createApplicationMenu(WScreen
*scr
)
603 menu
= wMenuCreate(scr
, NULL
, False
);
604 wMenuAddCallback(menu
, _("Unhide Here"), unhideHereCallback
, NULL
);
605 wMenuAddCallback(menu
, _("Hide"), hideCallback
, NULL
);
606 wMenuAddCallback(menu
, _("Set Icon..."), setIconCallback
, NULL
);
607 wMenuAddCallback(menu
, _("Kill"), killCallback
, NULL
);
614 openApplicationMenu(WApplication
*wapp
, int x
, int y
)
617 WScreen
*scr
= wapp
->main_window_desc
->screen_ptr
;
620 if (!scr
->icon_menu
) {
621 scr
->icon_menu
= createApplicationMenu(scr
);
622 free(scr
->icon_menu
->entries
[1]->text
);
625 menu
= scr
->icon_menu
;
627 if (wapp
->flags
.hidden
) {
628 menu
->entries
[1]->text
= _("Unhide");
630 menu
->entries
[1]->text
= _("Hide");
633 menu
->flags
.realized
= 0;
636 x
-= menu
->frame
->core
->width
/2;
637 if (x
+ menu
->frame
->core
->width
> scr
->scr_width
)
638 x
= scr
->scr_width
- menu
->frame
->core
->width
;
642 /* set client data */
643 for (i
= 0; i
< menu
->entry_no
; i
++) {
644 menu
->entries
[i
]->clientdata
= wapp
;
646 wMenuMapAt(menu
, x
, y
, False
);
650 /******************************************************************/
653 iconExpose(WObjDescriptor
*desc
, XEvent
*event
)
655 wAppIconPaint(desc
->parent
);
660 iconDblClick(WObjDescriptor
*desc
, XEvent
*event
)
662 WAppIcon
*aicon
= desc
->parent
;
664 WScreen
*scr
= aicon
->icon
->core
->screen_ptr
;
667 #ifndef REDUCE_APPICONS
668 assert(aicon
->icon
->owner
!=NULL
);
670 if (aicon
->icon
->owner
== NULL
) {
671 fprintf(stderr
, "Double-click disabled: missing main window.\n");
676 wapp
= wApplicationOf(aicon
->icon
->owner
->main_window
);
679 wwarning("could not find application descriptor for app icon!!");
683 #ifdef REDUCE_APPICONS
685 fprintf(stderr
, "Double-click disabled: missing wapp.\n");
688 #endif /* REDUCE_APPICONS */
690 unhideHere
= (event
->xbutton
.state
& ShiftMask
);
692 /* go to the last workspace that the user worked on the app */
693 if (!unhideHere
&& wapp
->last_workspace
!= scr
->current_workspace
)
694 wWorkspaceChange(scr
, wapp
->last_workspace
);
696 wUnhideApplication(wapp
, event
->xbutton
.button
==Button2
, unhideHere
);
698 if (event
->xbutton
.state
& MOD_MASK
) {
699 wHideOtherApplications(aicon
->icon
->owner
);
705 appIconMouseDown(WObjDescriptor
*desc
, XEvent
*event
)
707 WAppIcon
*aicon
= desc
->parent
;
708 WIcon
*icon
= aicon
->icon
;
710 int x
=aicon
->x_pos
, y
=aicon
->y_pos
;
711 int dx
=event
->xbutton
.x
, dy
=event
->xbutton
.y
;
714 int superfluous
= wPreferences
.superfluous
; /* we catch it to avoid problems */
715 WScreen
*scr
= icon
->core
->screen_ptr
;
716 WWorkspace
*workspace
= scr
->workspaces
[scr
->current_workspace
];
717 int shad_x
= 0, shad_y
= 0, docking
=0, dockable
, collapsed
= 0;
719 int clickButton
= event
->xbutton
.button
;
723 if (aicon
->editing
|| WCHECK_STATE(WSTATE_MODAL
))
726 if (IsDoubleClick(scr
, event
)) {
727 iconDblClick(desc
, event
);
731 if (event
->xbutton
.button
== Button3
) {
732 WObjDescriptor
*desc
;
733 WApplication
*wapp
= wApplicationOf(aicon
->icon
->owner
->main_window
);
738 if (event
->xbutton
.send_event
&&
739 XGrabPointer(dpy
, aicon
->icon
->core
->window
, True
, ButtonMotionMask
740 |ButtonReleaseMask
|ButtonPressMask
, GrabModeAsync
,
741 GrabModeAsync
, None
, None
, CurrentTime
) !=GrabSuccess
) {
742 wwarning("pointer grab failed for appicon menu");
746 openApplicationMenu(wapp
, event
->xbutton
.x_root
,
747 event
->xbutton
.y_root
);
749 /* allow drag select of menu */
750 desc
= &scr
->icon_menu
->menu
->descriptor
;
751 event
->xbutton
.send_event
= True
;
752 (*desc
->handle_mousedown
)(desc
, event
);
759 if (event
->xbutton
.state
& MOD_MASK
)
760 wLowerFrame(icon
->core
);
762 wRaiseFrame(icon
->core
);
765 if (XGrabPointer(dpy
, icon
->core
->window
, True
, ButtonMotionMask
766 |ButtonReleaseMask
|ButtonPressMask
, GrabModeAsync
,
767 GrabModeAsync
, None
, None
, CurrentTime
) !=GrabSuccess
) {
768 wwarning("pointer grab failed for appicon move");
771 if (wPreferences
.flags
.nodock
&& wPreferences
.flags
.noclip
)
774 dockable
= canBeDocked(icon
->owner
);
776 wins
[0] = icon
->core
->window
;
777 wins
[1] = scr
->dock_shadow
;
778 XRestackWindows(dpy
, wins
, 2);
780 if (icon
->pixmap
!=None
)
781 ghost
= MakeGhostIcon(scr
, icon
->pixmap
);
783 ghost
= MakeGhostIcon(scr
, icon
->core
->window
);
784 XSetWindowBackgroundPixmap(dpy
, scr
->dock_shadow
,
786 XClearWindow(dpy
, scr
->dock_shadow
);
790 WMMaskEvent(dpy
, PointerMotionMask
|ButtonReleaseMask
|ButtonPressMask
791 |ButtonMotionMask
|ExposureMask
, &ev
);
799 if (abs(dx
-ev
.xmotion
.x
)>=MOVE_THRESHOLD
800 || abs(dy
-ev
.xmotion
.y
)>=MOVE_THRESHOLD
) {
801 XChangeActivePointerGrab(dpy
, ButtonMotionMask
802 |ButtonReleaseMask
|ButtonPressMask
,
803 wCursor
[WCUR_MOVE
], CurrentTime
);
809 x
= ev
.xmotion
.x_root
- dx
;
810 y
= ev
.xmotion
.y_root
- dy
;
811 XMoveWindow(dpy
, icon
->core
->window
, x
, y
);
814 if (scr
->dock
&& wDockSnapIcon(scr
->dock
, aicon
, x
, y
,
816 shad_x
= scr
->dock
->x_pos
+ ix
*wPreferences
.icon_size
;
817 shad_y
= scr
->dock
->y_pos
+ iy
*wPreferences
.icon_size
;
819 if (scr
->last_dock
!= scr
->dock
&& collapsed
) {
820 scr
->last_dock
->collapsed
= 1;
821 wDockHideIcons(scr
->last_dock
);
824 if (!collapsed
&& (collapsed
= scr
->dock
->collapsed
)) {
825 scr
->dock
->collapsed
= 0;
826 wDockShowIcons(scr
->dock
);
829 if (scr
->dock
->auto_raise_lower
)
830 wDockRaise(scr
->dock
);
832 scr
->last_dock
= scr
->dock
;
834 XMoveWindow(dpy
, scr
->dock_shadow
, shad_x
, shad_y
);
836 XMapWindow(dpy
, scr
->dock_shadow
);
839 } else if (workspace
->clip
&&
840 wDockSnapIcon(workspace
->clip
, aicon
, x
, y
,
842 shad_x
= workspace
->clip
->x_pos
+ ix
*wPreferences
.icon_size
;
843 shad_y
= workspace
->clip
->y_pos
+ iy
*wPreferences
.icon_size
;
845 if (scr
->last_dock
!= workspace
->clip
&& collapsed
) {
846 scr
->last_dock
->collapsed
= 1;
847 wDockHideIcons(scr
->last_dock
);
850 if (!collapsed
&& (collapsed
= workspace
->clip
->collapsed
)) {
851 workspace
->clip
->collapsed
= 0;
852 wDockShowIcons(workspace
->clip
);
855 if (workspace
->clip
->auto_raise_lower
)
856 wDockRaise(workspace
->clip
);
858 scr
->last_dock
= workspace
->clip
;
860 XMoveWindow(dpy
, scr
->dock_shadow
, shad_x
, shad_y
);
862 XMapWindow(dpy
, scr
->dock_shadow
);
865 } else if (docking
) {
866 XUnmapWindow(dpy
, scr
->dock_shadow
);
877 if (ev
.xbutton
.button
!= clickButton
)
879 XUngrabPointer(dpy
, CurrentTime
);
884 /* icon is trying to be docked */
885 SlideWindow(icon
->core
->window
, x
, y
, shad_x
, shad_y
);
886 XUnmapWindow(dpy
, scr
->dock_shadow
);
887 docked
= wDockAttachIcon(scr
->last_dock
, aicon
, ix
, iy
);
888 if (scr
->last_dock
->auto_collapse
) {
891 if (workspace
->clip
&&
892 workspace
->clip
!= scr
->last_dock
&&
893 workspace
->clip
->auto_raise_lower
)
894 wDockLower(workspace
->clip
);
897 /* If icon could not be docked, slide it back to the old
899 SlideWindow(icon
->core
->window
, x
, y
, aicon
->x_pos
,
904 wSoundPlay(WMSOUND_DOCK
);
907 XMoveWindow(dpy
, icon
->core
->window
, x
, y
);
910 if (workspace
->clip
&& workspace
->clip
->auto_raise_lower
)
911 wDockLower(workspace
->clip
);
914 scr
->last_dock
->collapsed
= 1;
915 wDockHideIcons(scr
->last_dock
);
920 XFreePixmap(dpy
, ghost
);
921 XSetWindowBackground(dpy
, scr
->dock_shadow
, scr
->white_pixel
);
924 if (wPreferences
.auto_arrange_icons
)
925 wArrangeIcons(scr
, True
);
932 puts("End icon move");