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"
49 * icon_file for the dock is got from the preferences file by
50 * using the classname/instancename
53 /**** Global variables ****/
54 extern Cursor wCursor
[WCUR_LAST
];
55 extern WPreferences wPreferences
;
57 #define MOD_MASK wPreferences.modifier_mask
59 void appIconMouseDown(WObjDescriptor
*desc
, XEvent
*event
);
60 static void iconDblClick(WObjDescriptor
*desc
, XEvent
*event
);
61 static void iconExpose(WObjDescriptor
*desc
, XEvent
*event
);
66 wAppIconCreateForDock(WScreen
*scr
, char *command
, char *wm_instance
,
67 char *wm_class
, int tile
)
72 dicon
= wmalloc(sizeof(WAppIcon
));
74 memset(dicon
, 0, sizeof(WAppIcon
));
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
;
86 dicon
->command
= wstrdup(command
);
89 dicon
->wm_class
= wstrdup(wm_class
);
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
);
101 path
= FindImage(wPreferences
.icon_path
, path
);
103 dicon
->icon
= wIconCreateWithIconFile(scr
, path
, tile
);
106 #ifdef REDUCE_APPICONS
109 #ifdef DEMATERIALIZE_ICON
111 XSetWindowAttributes attribs
;
112 attribs
.save_under
= True
;
113 XChangeWindowAttributes(dpy
, dicon
->icon
->core
->window
,
114 CWSaveUnder
, &attribs
);
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
);
131 wAppIconCreate(WWindow
*leader_win
)
134 #ifdef REDUCE_APPICONS
136 WAppIconAppList
*applist
;
137 char *tinstance
, *tclass
;
139 WScreen
*scr
= leader_win
->screen_ptr
;
141 aicon
= wmalloc(sizeof(WAppIcon
));
143 memset(aicon
, 0, sizeof(WAppIcon
));
144 #ifdef REDUCE_APPICONS
145 applist
= wmalloc(sizeof(WAppIconAppList
));
146 memset(applist
, 0, sizeof(WAppIconAppList
));
147 applist
->wapp
= wApplicationOf(leader_win
->main_window
);
148 aicon
->applist
= applist
;
149 if (applist
->wapp
== NULL
) {
150 /* Something's wrong. wApplicationOf() should always return a
151 * valid structure. Rather than violate assumptions, bail. -cls
163 aicon
->next
= scr
->app_icon_list
;
164 if (scr
->app_icon_list
) {
165 #ifndef REDUCE_APPICONS
166 scr
->app_icon_list
->prev
= aicon
;
168 /* If we aren't going to have a match, jump straight to new appicon */
169 if (leader_win
->wm_class
== NULL
|| leader_win
->wm_class
== NULL
)
172 atmp
= scr
->app_icon_list
;
174 while (atmp
!= NULL
) {
175 if ((tinstance
= atmp
->wm_instance
) == NULL
)
177 if ((tclass
= atmp
->wm_class
) == NULL
)
179 if ((strcmp(leader_win
->wm_class
, tclass
) == 0) &&
180 (strcmp(leader_win
->wm_instance
, tinstance
) == 0))
182 /* We have a winner */
185 applist
->next
= atmp
->applist
;
187 atmp
->applist
->prev
= applist
;
188 atmp
->applist
= applist
;
191 wDockSimulateLaunch(atmp
->dock
, atmp
);
199 scr
->app_icon_list
->prev
= aicon
;
201 #endif /* REDUCE_APPICONS */
203 scr
->app_icon_list
= aicon
;
205 if (leader_win
->wm_class
)
206 aicon
->wm_class
= wstrdup(leader_win
->wm_class
);
207 if (leader_win
->wm_instance
)
208 aicon
->wm_instance
= wstrdup(leader_win
->wm_instance
);
209 #ifdef REDUCE_APPICONS
213 aicon
->icon
= wIconCreate(leader_win
);
214 #ifdef DEMATERIALIZE_ICON
216 XSetWindowAttributes attribs
;
217 attribs
.save_under
= True
;
218 XChangeWindowAttributes(dpy
, aicon
->icon
->core
->window
,
219 CWSaveUnder
, &attribs
);
223 /* will be overriden if docked */
224 aicon
->icon
->core
->descriptor
.handle_mousedown
= appIconMouseDown
;
225 aicon
->icon
->core
->descriptor
.handle_expose
= iconExpose
;
226 aicon
->icon
->core
->descriptor
.parent_type
= WCLASS_APPICON
;
227 aicon
->icon
->core
->descriptor
.parent
= aicon
;
228 AddToStackList(aicon
->icon
->core
);
229 aicon
->icon
->show_title
= 0;
230 wIconUpdate(aicon
->icon
);
237 wAppIconDestroy(WAppIcon
*aicon
)
239 WScreen
*scr
= aicon
->icon
->core
->screen_ptr
;
240 #ifdef REDUCE_APPICONS
241 WAppIconAppList
*aptmp
;
244 RemoveFromStackList(aicon
->icon
->core
);
245 wIconDestroy(aicon
->icon
);
247 free(aicon
->command
);
249 if (aicon
->dnd_command
)
250 free(aicon
->dnd_command
);
252 if (aicon
->wm_instance
)
253 free(aicon
->wm_instance
);
255 free(aicon
->wm_class
);
256 #ifdef REDUCE_APPICONS
257 /* There should never be a list but just in case */
258 if (aicon
->applist
!= NULL
) {
259 aptmp
= aicon
->applist
;
260 while (aptmp
->next
) {
268 if (aicon
== scr
->app_icon_list
) {
270 aicon
->next
->prev
= NULL
;
271 scr
->app_icon_list
= aicon
->next
;
275 aicon
->next
->prev
= aicon
->prev
;
277 aicon
->prev
->next
= aicon
->next
;
280 aicon
->destroyed
= 1;
288 drawCorner(WIcon
*icon
, WWindow
*wwin
, int active
)
290 WScreen
*scr
= wwin
->screen_ptr
;
301 gc
=scr
->focused_texture
->any
.gc
;
303 gc
=scr
->unfocused_texture
->any
.gc
;
305 XFillPolygon(dpy
, icon
->core
->window
, gc
, points
, 3,
306 Convex
, CoordModeOrigin
);
308 #endif /* NEWAPPICON */
312 wAppIconMove(WAppIcon
*aicon
, int x
, int y
)
314 XMoveWindow(dpy
, aicon
->icon
->core
->window
, x
, y
);
322 updateDockNumbers(WScreen
*scr
)
327 XGCValues my_gc_values
;
328 unsigned long my_v_mask
= (GCForeground
);
329 WAppIcon
*dicon
= scr
->dock
->icon_array
[0];
331 my_gc_values
.foreground
= scr
->white_pixel
;
332 numbers_gc
= XCreateGC(dpy
, dicon
->icon
->core
->window
,
333 my_v_mask
, &my_gc_values
);
335 ws_numbers
= malloc(20);
336 sprintf(ws_numbers
, "%i [ %i ]", scr
->current_workspace
+1,
337 ((scr
->current_workspace
/10)+1));
338 length
= strlen(ws_numbers
);
340 XClearArea(dpy
, dicon
->icon
->core
->window
, 2, 2, 50,
341 scr
->icon_title_font
->y
+1, False
);
344 XSetFont(dpy
, numbers_gc
, scr
->icon_title_font
->font
->fid
);
345 XSetForeground(dpy
, numbers_gc
, scr
->black_pixel
);
346 XDrawString(dpy
, dicon
->icon
->core
->window
,
347 numbers_gc
, 4, scr
->icon_title_font
->y
+3, ws_numbers
, length
);
348 XSetForeground(dpy
, numbers_gc
, scr
->white_pixel
);
349 XDrawString(dpy
, dicon
->icon
->core
->window
,
350 numbers_gc
, 3, scr
->icon_title_font
->y
+2, ws_numbers
, length
);
352 XSetForeground(dpy
, numbers_gc
, scr
->black_pixel
);
353 XmbDrawString(dpy
, dicon
->icon
->core
->window
,
354 scr
->icon_title_font
->font
, numbers_gc
, 4,
355 scr
->icon_title_font
->y
+3, ws_numbers
, length
);
356 XSetForeground(dpy
, numbers_gc
, scr
->white_pixel
);
357 XmbDrawString(dpy
, dicon
->icon
->core
->window
,
358 scr
->icon_title_font
->font
, numbers_gc
, 3,
359 scr
->icon_title_font
->y
+2, ws_numbers
, length
);
362 XFreeGC(dpy
, numbers_gc
);
365 #endif /* WS_INDICATOR */
369 wAppIconPaint(WAppIcon
*aicon
)
371 WScreen
*scr
= aicon
->icon
->core
->screen_ptr
;
373 wIconPaint(aicon
->icon
);
377 if (aicon
->docked
&& scr
->dock
&& aicon
->yindex
==0)
378 updateDockNumbers(scr
);
380 if (scr
->dock_dots
&& aicon
->docked
&& !aicon
->running
381 && aicon
->command
!=NULL
) {
382 XSetClipMask(dpy
, scr
->copy_gc
, scr
->dock_dots
->mask
);
383 XSetClipOrigin(dpy
, scr
->copy_gc
, 0, 0);
384 XCopyArea(dpy
, scr
->dock_dots
->image
, aicon
->icon
->core
->window
,
385 scr
->copy_gc
, 0, 0, scr
->dock_dots
->width
,
386 scr
->dock_dots
->height
, 0, 0);
392 wapp
= wApplicationOf(aicon
->main_window
);
394 if(wapp
->flags
.hidden
){
395 XSetClipMask(dpy
, scr
->copy_gc
, scr
->dock_dots
->mask
);
396 XSetClipOrigin(dpy
, scr
->copy_gc
, 0, 0);
397 XCopyArea(dpy
, scr
->dock_dots
->image
, aicon
->icon
->core
->window
,
398 scr
->copy_gc
, 0, 0, 7,
399 scr
->dock_dots
->height
, 0, 0);
402 #endif /* HIDDENDOT */
405 if (!wPreferences
.strict_ns
&& aicon
->icon
->owner
!=NULL
) {
407 if (aicon
->main_window
==None
) {
408 active
= (aicon
->icon
->owner
->flags
.focused
? 1 : 0);
412 wapp
= wApplicationOf(aicon
->main_window
);
414 active
= aicon
->icon
->owner
->flags
.focused
;
415 wwarning("error in wAppIconPaint(). Please report it");
417 active
= wapp
->main_window_desc
->flags
.focused
;
418 if (wapp
->main_window_desc
->flags
.hidden
419 || !wapp
->main_window_desc
->flags
.mapped
)
424 drawCorner(aicon
->icon
, aicon
->icon
->owner
, active
);
426 #endif /* NEWAPPICON */
428 XSetClipMask(dpy
, scr
->copy_gc
, None
);
429 if (aicon
->launching
) {
430 XFillRectangle(dpy
, aicon
->icon
->core
->window
, scr
->stipple_gc
,
431 0, 0, wPreferences
.icon_size
, wPreferences
.icon_size
);
437 #define canBeDocked(wwin) ((wwin) && ((wwin)->wm_class||(wwin)->wm_instance))
439 #ifdef REDUCE_APPICONS
441 wAppIconReduceAppCount(WApplication
*wapp
)
443 WAppIconAppList
*applist
;
448 if (wapp
->app_icon
== NULL
)
451 /* If given a main window, check the applist
452 * and remove the if it exists
454 applist
= wapp
->app_icon
->applist
;
455 while (applist
!= NULL
) {
456 if (applist
->wapp
== wapp
) {
457 /* If this app owns the appicon, change the appicon's
458 * owner to the next app in the list or NULL
460 if (wapp
->app_icon
->icon
->owner
== applist
->wapp
->main_window_desc
)
463 wapp
->app_icon
->icon
->owner
= applist
->next
->wapp
->main_window_desc
;
464 } else if (applist
->prev
) {
465 wapp
->app_icon
->icon
->owner
= applist
->prev
->wapp
->main_window_desc
;
467 wapp
->app_icon
->icon
->owner
= NULL
;
471 applist
->prev
->next
= applist
->next
;
474 applist
->next
->prev
= applist
->prev
;
476 if (applist
== wapp
->app_icon
->applist
)
477 wapp
->app_icon
->applist
= applist
->next
;
481 if (wapp
->app_icon
->applist
!= NULL
)
482 wapp
->app_icon
->main_window
= wapp
->app_icon
->applist
->wapp
->main_window
;
484 return (--wapp
->app_icon
->num_apps
);
486 applist
= applist
->next
;
488 return (--wapp
->app_icon
->num_apps
);
494 hideCallback(WMenu
*menu
, WMenuEntry
*entry
)
496 WApplication
*wapp
= (WApplication
*)entry
->clientdata
;
498 if (wapp
->flags
.hidden
) {
499 wWorkspaceChange(menu
->menu
->screen_ptr
, wapp
->last_workspace
);
500 wUnhideApplication(wapp
, False
, False
);
502 wHideApplication(wapp
);
508 unhideHereCallback(WMenu
*menu
, WMenuEntry
*entry
)
510 WApplication
*wapp
= (WApplication
*)entry
->clientdata
;
512 wUnhideApplication(wapp
, False
, True
);
517 setIconCallback(WMenu
*menu
, WMenuEntry
*entry
)
519 WAppIcon
*icon
= ((WApplication
*)entry
->clientdata
)->app_icon
;
529 scr
= icon
->icon
->core
->screen_ptr
;
533 result
= wIconChooserDialog(scr
, &file
, icon
->wm_instance
, icon
->wm_class
);
535 if (result
&& !icon
->destroyed
) {
540 if (!wIconChangeImageFile(icon
->icon
, file
)) {
541 wMessageDialog(scr
, _("Error"),
542 _("Could not open specified icon file"),
543 _("OK"), NULL
, NULL
);
545 wDefaultChangeIcon(scr
, icon
->wm_instance
, icon
->wm_class
, file
);
557 killCallback(WMenu
*menu
, WMenuEntry
*entry
)
559 WApplication
*wapp
= (WApplication
*)entry
->clientdata
;
562 if (!WCHECK_STATE(WSTATE_NORMAL
))
565 WCHANGE_STATE(WSTATE_MODAL
);
567 assert(entry
->clientdata
!=NULL
);
569 buffer
= wstrappend(wapp
->app_icon
? wapp
->app_icon
->wm_class
: NULL
,
570 _(" will be forcibly closed.\n"
571 "Any unsaved changes will be lost.\n"
574 wretain(wapp
->main_window_desc
);
575 if (wPreferences
.dont_confirm_kill
576 || wMessageDialog(menu
->frame
->screen_ptr
, _("Kill Application"),
577 buffer
, _("Yes"), _("No"), NULL
)==WAPRDefault
) {
578 if (!wapp
->main_window_desc
->flags
.destroyed
)
579 wClientKill(wapp
->main_window_desc
);
581 wrelease(wapp
->main_window_desc
);
585 WCHANGE_STATE(WSTATE_NORMAL
);
590 createApplicationMenu(WScreen
*scr
)
594 menu
= wMenuCreate(scr
, NULL
, False
);
595 wMenuAddCallback(menu
, _("Unhide Here"), unhideHereCallback
, NULL
);
596 wMenuAddCallback(menu
, _("Hide"), hideCallback
, NULL
);
597 wMenuAddCallback(menu
, _("Set Icon..."), setIconCallback
, NULL
);
598 wMenuAddCallback(menu
, _("Kill"), killCallback
, NULL
);
605 openApplicationMenu(WApplication
*wapp
, int x
, int y
)
608 WScreen
*scr
= wapp
->main_window_desc
->screen_ptr
;
611 if (!scr
->icon_menu
) {
612 scr
->icon_menu
= createApplicationMenu(scr
);
613 free(scr
->icon_menu
->entries
[1]->text
);
616 menu
= scr
->icon_menu
;
618 if (wapp
->flags
.hidden
) {
619 menu
->entries
[1]->text
= _("Unhide");
621 menu
->entries
[1]->text
= _("Hide");
624 menu
->flags
.realized
= 0;
627 x
-= menu
->frame
->core
->width
/2;
628 if (x
+ menu
->frame
->core
->width
> scr
->scr_width
)
629 x
= scr
->scr_width
- menu
->frame
->core
->width
;
633 /* set client data */
634 for (i
= 0; i
< menu
->entry_no
; i
++) {
635 menu
->entries
[i
]->clientdata
= wapp
;
637 wMenuMapAt(menu
, x
, y
, False
);
641 /******************************************************************/
644 iconExpose(WObjDescriptor
*desc
, XEvent
*event
)
646 wAppIconPaint(desc
->parent
);
651 iconDblClick(WObjDescriptor
*desc
, XEvent
*event
)
653 WAppIcon
*aicon
= desc
->parent
;
655 WScreen
*scr
= aicon
->icon
->core
->screen_ptr
;
658 #ifndef REDUCE_APPICONS
659 assert(aicon
->icon
->owner
!=NULL
);
661 if (aicon
->icon
->owner
== NULL
) {
662 fprintf(stderr
, "Double-click disabled: missing main window.\n");
667 wapp
= wApplicationOf(aicon
->icon
->owner
->main_window
);
670 wwarning("could not find application descriptor for app icon!!");
674 #ifdef REDUCE_APPICONS
676 fprintf(stderr
, "Double-click disabled: missing wapp.\n");
679 #endif /* REDUCE_APPICONS */
681 unhideHere
= (event
->xbutton
.state
& ShiftMask
);
683 /* go to the last workspace that the user worked on the app */
684 if (!unhideHere
&& wapp
->last_workspace
!= scr
->current_workspace
)
685 wWorkspaceChange(scr
, wapp
->last_workspace
);
687 wUnhideApplication(wapp
, event
->xbutton
.button
==Button2
, unhideHere
);
689 if (event
->xbutton
.state
& MOD_MASK
) {
690 wHideOtherApplications(aicon
->icon
->owner
);
696 appIconMouseDown(WObjDescriptor
*desc
, XEvent
*event
)
698 WAppIcon
*aicon
= desc
->parent
;
699 WIcon
*icon
= aicon
->icon
;
701 int x
=aicon
->x_pos
, y
=aicon
->y_pos
;
702 int dx
=event
->xbutton
.x
, dy
=event
->xbutton
.y
;
705 int superfluous
= wPreferences
.superfluous
; /* we catch it to avoid problems */
706 WScreen
*scr
= icon
->core
->screen_ptr
;
707 WWorkspace
*workspace
= scr
->workspaces
[scr
->current_workspace
];
708 int shad_x
= 0, shad_y
= 0, docking
=0, dockable
, collapsed
= 0;
710 int clickButton
= event
->xbutton
.button
;
713 if (aicon
->editing
|| WCHECK_STATE(WSTATE_MODAL
))
716 if (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 openApplicationMenu(wapp
, event
->xbutton
.x_root
,
729 event
->xbutton
.y_root
);
731 /* allow drag select of menu */
732 desc
= &scr
->icon_menu
->menu
->descriptor
;
733 event
->xbutton
.send_event
= True
;
734 (*desc
->handle_mousedown
)(desc
, event
);
741 if (event
->xbutton
.state
& MOD_MASK
)
742 wLowerFrame(icon
->core
);
744 wRaiseFrame(icon
->core
);
747 if (XGrabPointer(dpy
, icon
->core
->window
, True
, ButtonMotionMask
748 |ButtonReleaseMask
|ButtonPressMask
, GrabModeAsync
,
749 GrabModeAsync
, None
, None
, CurrentTime
) !=GrabSuccess
) {
750 wwarning("pointer grab failed for appicon move");
753 if (wPreferences
.flags
.nodock
&& wPreferences
.flags
.noclip
)
756 dockable
= canBeDocked(icon
->owner
);
760 WMMaskEvent(dpy
, PointerMotionMask
|ButtonReleaseMask
|ButtonPressMask
761 |ButtonMotionMask
|ExposureMask
, &ev
);
769 if (abs(dx
-ev
.xmotion
.x
)>=MOVE_THRESHOLD
770 || abs(dy
-ev
.xmotion
.y
)>=MOVE_THRESHOLD
) {
771 XChangeActivePointerGrab(dpy
, ButtonMotionMask
772 |ButtonReleaseMask
|ButtonPressMask
,
773 wCursor
[WCUR_MOVE
], CurrentTime
);
779 x
= ev
.xmotion
.x_root
- dx
;
780 y
= ev
.xmotion
.y_root
- dy
;
781 XMoveWindow(dpy
, icon
->core
->window
, x
, y
);
784 if (scr
->dock
&& wDockSnapIcon(scr
->dock
, aicon
, x
, y
,
786 shad_x
= scr
->dock
->x_pos
+ ix
*wPreferences
.icon_size
;
787 shad_y
= scr
->dock
->y_pos
+ iy
*wPreferences
.icon_size
;
789 if (scr
->last_dock
!= scr
->dock
&& collapsed
) {
790 scr
->last_dock
->collapsed
= 1;
791 wDockHideIcons(scr
->last_dock
);
794 if (!collapsed
&& (collapsed
= scr
->dock
->collapsed
)) {
795 scr
->dock
->collapsed
= 0;
796 wDockShowIcons(scr
->dock
);
799 if (scr
->dock
->auto_raise_lower
)
800 wDockRaise(scr
->dock
);
802 scr
->last_dock
= scr
->dock
;
804 XMoveWindow(dpy
, scr
->dock_shadow
, shad_x
, shad_y
);
808 wins
[0] = icon
->core
->window
;
809 wins
[1] = scr
->dock_shadow
;
810 XRestackWindows(dpy
, wins
, 2);
812 if (icon
->pixmap
!=None
)
813 ghost
= MakeGhostIcon(scr
, icon
->pixmap
);
815 ghost
= MakeGhostIcon(scr
, icon
->core
->window
);
816 XSetWindowBackgroundPixmap(dpy
, scr
->dock_shadow
,
818 XClearWindow(dpy
, scr
->dock_shadow
);
820 XMapWindow(dpy
, scr
->dock_shadow
);
823 } else if (workspace
->clip
&&
824 wDockSnapIcon(workspace
->clip
, aicon
, x
, y
,
826 shad_x
= workspace
->clip
->x_pos
+ ix
*wPreferences
.icon_size
;
827 shad_y
= workspace
->clip
->y_pos
+ iy
*wPreferences
.icon_size
;
829 if (scr
->last_dock
!= workspace
->clip
&& collapsed
) {
830 scr
->last_dock
->collapsed
= 1;
831 wDockHideIcons(scr
->last_dock
);
834 if (!collapsed
&& (collapsed
= workspace
->clip
->collapsed
)) {
835 workspace
->clip
->collapsed
= 0;
836 wDockShowIcons(workspace
->clip
);
839 if (workspace
->clip
->auto_raise_lower
)
840 wDockRaise(workspace
->clip
);
842 scr
->last_dock
= workspace
->clip
;
844 XMoveWindow(dpy
, scr
->dock_shadow
, shad_x
, shad_y
);
848 wins
[0] = icon
->core
->window
;
849 wins
[1] = scr
->dock_shadow
;
850 XRestackWindows(dpy
, wins
, 2);
852 if (icon
->pixmap
!=None
)
853 ghost
= MakeGhostIcon(scr
, icon
->pixmap
);
855 ghost
= MakeGhostIcon(scr
, icon
->core
->window
);
856 XSetWindowBackgroundPixmap(dpy
, scr
->dock_shadow
,
858 XClearWindow(dpy
, scr
->dock_shadow
);
860 XMapWindow(dpy
, scr
->dock_shadow
);
863 } else if (docking
) {
864 XUnmapWindow(dpy
, scr
->dock_shadow
);
875 if (ev
.xbutton
.button
!= clickButton
)
877 XUngrabPointer(dpy
, CurrentTime
);
882 /* icon is trying to be docked */
883 SlideWindow(icon
->core
->window
, x
, y
, shad_x
, shad_y
);
884 XUnmapWindow(dpy
, scr
->dock_shadow
);
885 docked
= wDockAttachIcon(scr
->last_dock
, aicon
, ix
, iy
);
886 if (scr
->last_dock
->auto_collapse
) {
889 if (workspace
->clip
&&
890 workspace
->clip
!= scr
->last_dock
&&
891 workspace
->clip
->auto_raise_lower
)
892 wDockLower(workspace
->clip
);
895 /* If icon could not be docked, slide it back to the old
897 SlideWindow(icon
->core
->window
, x
, y
, aicon
->x_pos
,
901 XMoveWindow(dpy
, icon
->core
->window
, x
, y
);
904 if (workspace
->clip
&& workspace
->clip
->auto_raise_lower
)
905 wDockLower(workspace
->clip
);
908 scr
->last_dock
->collapsed
= 1;
909 wDockHideIcons(scr
->last_dock
);
914 XFreePixmap(dpy
, ghost
);
915 XSetWindowBackground(dpy
, scr
->dock_shadow
, scr
->white_pixel
);
918 if (wPreferences
.auto_arrange_icons
)
919 wArrangeIcons(scr
, True
);
926 puts("End icon move");