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.
29 #include "buttonbar.h"
35 static bool BarShown
= false ;
36 static bool HideBarDelayed
= false ;
38 static void FindWMFrameAndBarPos (void)
40 XWindowAttributes wa
;
41 Window tile
, parent
, root
, *children
;
42 unsigned int nChildren
;
45 /* find window just under root, it is the wm frame icon */
46 /* (or DAWindow itself if none) */
48 tile
= parent
= DAWindow
;
49 while (parent
!= root
)
52 XQueryTree (DADisplay
, tile
,
53 &root
, &parent
, &children
, &nChildren
) ;
54 if (children
!= NULL
) XFree (children
) ;
57 /* container actually changed ? */
62 TODO: put this back once a solution has been found to avoid an X
63 error, when WMFrame has been destroyed while we were looking for our
64 new frame. Meanwhile, it seems acceptable to not unregister events
65 since in the normal case WMFrame is going to be destroyed !
67 /* remove events from old container (if this is not the first time) */
68 if (WMFrame
!= 0 && WMFrame
!= DAWindow
)
69 XSelectInput (DADisplay
, WMFrame
, 0) ;
72 /* add events to new container */
75 evMask
= StructureNotifyMask
; /* move/destroy */
77 evMask
|= EnterWindowMask
| LeaveWindowMask
;
78 XSelectInput (DADisplay
, tile
, evMask
) ;
84 XGetWindowAttributes (DADisplay
, WMFrame
, & wa
) ;
85 ButtonBar_SetPositionFromDockApp (wa
.x
, wa
.y
, wa
.width
, wa
.height
) ;
88 static void EnterApp (void)
90 if (Menu_HasChanged ())
97 ButtonBar_Rebuild () ;
98 /* adjust position depending on possible new size */
99 FindWMFrameAndBarPos () ;
104 HideBarDelayed
= false ;
107 static void LeaveBar (void)
111 HideBarDelayed
= false ;
114 static void LeaveApp (void)
118 ButtonBar_Unhighlight () ;
119 HideBarDelayed
= ! ClickOnly
;
123 static void InvokeBar (int x
, int y
)
126 h
= Menu_GetNbRows () ;
127 w
= Menu_GetNbColumns () ;
130 if (0 <= y
&& y
< h
&& 0 <= x
&& x
< w
)
135 if (entry
< Menu_GetNbEntries ())
137 system (Menu_GetEntryCommand (entry
)) ;
144 static void PressApp (int button
, int state
, int x
, int y
)
146 if (BarShown
) LeaveBar () ;
150 extern void Events_SetCallbacks (void)
153 XSetWindowAttributes ws
;
154 XWindowAttributes wa
;
156 events
.destroy
= NULL
;
157 events
.buttonPress
= PressApp
;
158 events
.buttonRelease
= NULL
;
159 events
.motion
= NULL
;
160 events
.enter
= (ClickOnly
? NULL
: EnterApp
) ;
161 events
.leave
= (ClickOnly
? NULL
: LeaveApp
) ;
163 DASetCallbacks (& events
) ;
165 /* update set of events we want to catch on the dock app */
166 XGetWindowAttributes (DADisplay
, DAWindow
, & wa
) ;
167 ws
.event_mask
= wa
.your_event_mask
168 | StructureNotifyMask
; /* move/reparent */
169 /* work around a bug in libdockapp: not selecting Enter/Leave events */
171 ws
.event_mask
|= EnterWindowMask
| LeaveWindowMask
;
172 XChangeWindowAttributes (DADisplay
, DAWindow
, CWEventMask
, & ws
) ;
175 extern void Events_Loop (void)
178 bool canShowBar
= true ;
182 /* get some event to process */
185 if (! DANextEventOrTimeout (& ev
, HideTimeout
))
189 continue ; /* restart waiting for an event */
194 XNextEvent (DADisplay
, & ev
) ;
196 /* event available, process it */
199 if (ev
.type
== EnterNotify
) /* catch entering any wmmenu window */
201 if (canShowBar
) EnterApp () ;
205 if (ev
.type
== LeaveNotify
) /* catch leaving any wmmenu window */
207 /* when cursor goes from icon to dock tile */
208 /* take care to not show the bar back if it is already hidden */
209 if (ev
.xany
.window
== DAWindow
)
210 canShowBar
= BarShown
;
214 if (ev
.xany
.window
== DAWindow
) switch (ev
.type
)
216 case ReparentNotify
:
217 case ConfigureNotify
:
218 /* find new WMFrame and update bar position */
219 FindWMFrameAndBarPos () ;
223 DAProcessEvent (& ev
) ;
227 if (ev
.xany
.window
== ButtonBarWindow
) switch (ev
.type
)
230 InvokeBar (ev
.xbutton
.x
, ev
.xbutton
.y
) ;
234 if (HighlightImage
!= 0) /* try to avoid func call */
236 ButtonBar_Highlight (
237 ev
.xmotion
.x
/TileXSize
, ev
.xmotion
.y
/TileYSize
) ;
242 if (ev
.xany
.window
== WMFrame
&& WMFrame
!= 0) switch (ev
.type
)
245 case ConfigureNotify
:
246 /* find new WMFrame and update bar position */
247 FindWMFrameAndBarPos () ;