2 List of events catched:
5 - button press and release => run a menu entry
6 - enter/leave => show/hide bar (if not -O click) and highlight (if set)
7 - pointer motion (if highlight set) => change highlight position
10 - button press => show/hide bar
11 - enter/leave (if not -O click) => show/hide bar
12 - move/reparent => find WMFrame and bar coords, update frame events.
15 - enter/leave (if not -O click) => show/hide bar
16 - move/destroy => find WMFrame and bar coords, update frame events.
18 NB: Move is actually part of a larger "Configure" event; Configure,
19 Reparent and Destroy events are catched with StructureNotifyMask.
25 #include <libdockapp/dockapp.h>
29 #include "buttonbar.h"
36 static bool BarShown
= false ;
37 static bool HideBarDelayed
= false ;
39 static void FindWMFrameAndBarPos (void)
41 XWindowAttributes wa
;
42 Window tile
, parent
, root
, *children
;
43 unsigned int nChildren
;
46 /* find window just under root, it is the wm frame icon */
47 /* (or DAWindow itself if none) */
49 tile
= parent
= DAWindow
;
50 while (parent
!= root
)
53 XQueryTree (DADisplay
, tile
,
54 &root
, &parent
, &children
, &nChildren
) ;
55 if (children
!= NULL
) XFree (children
) ;
58 /* container actually changed ? */
63 TODO: put this back once a solution has been found to avoid an X
64 error, when WMFrame has been destroyed while we were looking for our
65 new frame. Meanwhile, it seems acceptable to not unregister events
66 since in the normal case WMFrame is going to be destroyed !
68 /* remove events from old container (if this is not the first time) */
69 if (WMFrame
!= 0 && WMFrame
!= DAWindow
)
70 XSelectInput (DADisplay
, WMFrame
, 0) ;
73 /* add events to new container */
76 evMask
= StructureNotifyMask
; /* move/destroy */
78 evMask
|= EnterWindowMask
| LeaveWindowMask
;
79 XSelectInput (DADisplay
, tile
, evMask
) ;
85 XGetWindowAttributes (DADisplay
, WMFrame
, & wa
) ;
86 ButtonBar_SetPositionFromDockApp (wa
.x
, wa
.y
, wa
.width
, wa
.height
) ;
89 static void EnterApp (void)
91 if (Menu_HasChanged ())
98 ButtonBar_Rebuild () ;
99 /* adjust position depending on possible new size */
100 FindWMFrameAndBarPos () ;
105 HideBarDelayed
= false ;
108 static void LeaveBar (void)
112 HideBarDelayed
= false ;
115 static void LeaveApp (void)
119 ButtonBar_Unhighlight () ;
120 HideBarDelayed
= ! ClickOnly
;
124 static void InvokeBar (int x
, int y
)
127 h
= Menu_GetNbRows () ;
128 w
= Menu_GetNbColumns () ;
131 if (0 <= y
&& y
< h
&& 0 <= x
&& x
< w
)
136 if (entry
< Menu_GetNbEntries ())
140 command
= Menu_GetEntryCommand (entry
);
141 if (system (command
) == -1)
142 warn("'%s' returned an error\n", command
);
149 static void PressApp (int button
, int state
, int x
, int y
)
155 if (BarShown
) LeaveBar () ;
159 extern void Events_SetCallbacks (void)
162 XSetWindowAttributes ws
;
163 XWindowAttributes wa
;
165 events
.destroy
= NULL
;
166 events
.buttonPress
= PressApp
;
167 events
.buttonRelease
= NULL
;
168 events
.motion
= NULL
;
169 events
.enter
= (ClickOnly
? NULL
: EnterApp
) ;
170 events
.leave
= (ClickOnly
? NULL
: LeaveApp
) ;
172 DASetCallbacks (& events
) ;
174 /* update set of events we want to catch on the dock app */
175 XGetWindowAttributes (DADisplay
, DAWindow
, & wa
) ;
176 ws
.event_mask
= wa
.your_event_mask
177 | StructureNotifyMask
; /* move/reparent */
178 /* work around a bug in libdockapp: not selecting Enter/Leave events */
180 ws
.event_mask
|= EnterWindowMask
| LeaveWindowMask
;
181 XChangeWindowAttributes (DADisplay
, DAWindow
, CWEventMask
, & ws
) ;
184 extern void Events_Loop (void)
187 bool canShowBar
= true ;
191 /* get some event to process */
194 if (! DANextEventOrTimeout (& ev
, HideTimeout
))
198 continue ; /* restart waiting for an event */
203 XNextEvent (DADisplay
, & ev
) ;
205 /* event available, process it */
208 if (ev
.type
== EnterNotify
) /* catch entering any wmmenu window */
210 if (canShowBar
) EnterApp () ;
214 if (ev
.type
== LeaveNotify
) /* catch leaving any wmmenu window */
216 /* when cursor goes from icon to dock tile */
217 /* take care to not show the bar back if it is already hidden */
218 if (ev
.xany
.window
== DAWindow
)
219 canShowBar
= BarShown
;
223 if (ev
.xany
.window
== DAWindow
) switch (ev
.type
)
225 case ReparentNotify
:
226 case ConfigureNotify
:
227 /* find new WMFrame and update bar position */
228 FindWMFrameAndBarPos () ;
232 DAProcessEvent (& ev
) ;
236 if (ev
.xany
.window
== ButtonBarWindow
) switch (ev
.type
)
239 InvokeBar (ev
.xbutton
.x
, ev
.xbutton
.y
) ;
243 if (HighlightImage
!= 0) /* try to avoid func call */
245 ButtonBar_Highlight (
246 ev
.xmotion
.x
/TileXSize
, ev
.xmotion
.y
/TileYSize
) ;
251 if (ev
.xany
.window
== WMFrame
&& WMFrame
!= 0) switch (ev
.type
)
254 case ConfigureNotify
:
255 /* find new WMFrame and update bar position */
256 FindWMFrameAndBarPos () ;