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"
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
)
151 if (BarShown
) LeaveBar () ;
155 extern void Events_SetCallbacks (void)
158 XSetWindowAttributes ws
;
159 XWindowAttributes wa
;
161 events
.destroy
= NULL
;
162 events
.buttonPress
= PressApp
;
163 events
.buttonRelease
= NULL
;
164 events
.motion
= NULL
;
165 events
.enter
= (ClickOnly
? NULL
: EnterApp
) ;
166 events
.leave
= (ClickOnly
? NULL
: LeaveApp
) ;
168 DASetCallbacks (& events
) ;
170 /* update set of events we want to catch on the dock app */
171 XGetWindowAttributes (DADisplay
, DAWindow
, & wa
) ;
172 ws
.event_mask
= wa
.your_event_mask
173 | StructureNotifyMask
; /* move/reparent */
174 /* work around a bug in libdockapp: not selecting Enter/Leave events */
176 ws
.event_mask
|= EnterWindowMask
| LeaveWindowMask
;
177 XChangeWindowAttributes (DADisplay
, DAWindow
, CWEventMask
, & ws
) ;
180 extern void Events_Loop (void)
183 bool canShowBar
= true ;
187 /* get some event to process */
190 if (! DANextEventOrTimeout (& ev
, HideTimeout
))
194 continue ; /* restart waiting for an event */
199 XNextEvent (DADisplay
, & ev
) ;
201 /* event available, process it */
204 if (ev
.type
== EnterNotify
) /* catch entering any wmmenu window */
206 if (canShowBar
) EnterApp () ;
210 if (ev
.type
== LeaveNotify
) /* catch leaving any wmmenu window */
212 /* when cursor goes from icon to dock tile */
213 /* take care to not show the bar back if it is already hidden */
214 if (ev
.xany
.window
== DAWindow
)
215 canShowBar
= BarShown
;
219 if (ev
.xany
.window
== DAWindow
) switch (ev
.type
)
221 case ReparentNotify
:
222 case ConfigureNotify
:
223 /* find new WMFrame and update bar position */
224 FindWMFrameAndBarPos () ;
228 DAProcessEvent (& ev
) ;
232 if (ev
.xany
.window
== ButtonBarWindow
) switch (ev
.type
)
235 InvokeBar (ev
.xbutton
.x
, ev
.xbutton
.y
) ;
239 if (HighlightImage
!= 0) /* try to avoid func call */
241 ButtonBar_Highlight (
242 ev
.xmotion
.x
/TileXSize
, ev
.xmotion
.y
/TileYSize
) ;
247 if (ev
.xany
.window
== WMFrame
&& WMFrame
!= 0) switch (ev
.type
)
250 case ConfigureNotify
:
251 /* find new WMFrame and update bar position */
252 FindWMFrameAndBarPos () ;