wmmenu: Fix -Wunused-result compiler warning.
[dockapps.git] / wmmenu / events.c
blob04986355b0eff8897210948370645b79b40d856e
1 /*
2 List of events catched:
4 button bar window:
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
9 menu icon:
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.
14 WMFrame (if some):
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.
23 #include <stdlib.h>
25 #include <dockapp.h>
27 #include "types.h"
28 #include "events.h"
29 #include "buttonbar.h"
30 #include "options.h"
31 #include "menu.h"
32 #include "xobjects.h"
33 #include "pixmaps.h"
34 #include "error.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 ;
44 long evMask ;
46 /* find window just under root, it is the wm frame icon */
47 /* (or DAWindow itself if none) */
48 root = 0 ;
49 tile = parent = DAWindow ;
50 while (parent != root)
52 tile = parent ;
53 XQueryTree (DADisplay, tile,
54 &root, &parent, &children, &nChildren) ;
55 if (children != NULL) XFree (children) ;
58 /* container actually changed ? */
59 if (WMFrame != tile)
61 #if 0
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) ;
71 #endif
73 /* add events to new container */
74 if (tile != DAWindow)
76 evMask = StructureNotifyMask ; /* move/destroy */
77 if (! ClickOnly)
78 evMask |= EnterWindowMask | LeaveWindowMask ;
79 XSelectInput (DADisplay, tile, evMask) ;
82 WMFrame = tile ;
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 ())
93 Menu_Reload () ;
95 Pixmaps_LoadMenu () ;
96 Pixmaps_LoadTile () ;
98 ButtonBar_Rebuild () ;
99 /* adjust position depending on possible new size */
100 FindWMFrameAndBarPos () ;
103 ButtonBar_Show () ;
104 BarShown = true ;
105 HideBarDelayed = false ;
108 static void LeaveBar (void)
110 ButtonBar_Hide () ;
111 BarShown = false ;
112 HideBarDelayed = false ;
115 static void LeaveApp (void)
117 if (BarShown)
119 ButtonBar_Unhighlight () ;
120 HideBarDelayed = ! ClickOnly ;
124 static void InvokeBar (int x, int y)
126 int h, w ;
127 h = Menu_GetNbRows () ;
128 w = Menu_GetNbColumns () ;
129 x /= TileXSize ;
130 y /= TileYSize ;
131 if (0 <= y && y < h && 0 <= x && x < w)
133 int entry ;
134 entry = y + h*x ;
136 if (entry < Menu_GetNbEntries ())
138 const char *command;
140 command = Menu_GetEntryCommand (entry);
141 if (system (command) == -1)
142 warn("'%s' returned an error\n", command);
146 LeaveBar () ;
149 static void PressApp (int button, int state, int x, int y)
151 if (BarShown) LeaveBar () ;
152 else EnterApp () ;
155 extern void Events_SetCallbacks (void)
157 DACallbacks events ;
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 */
175 if (! ClickOnly)
176 ws.event_mask |= EnterWindowMask | LeaveWindowMask ;
177 XChangeWindowAttributes (DADisplay, DAWindow, CWEventMask, & ws) ;
180 extern void Events_Loop (void)
182 XEvent ev ;
183 bool canShowBar = true ;
185 while (true)
187 /* get some event to process */
188 if (HideBarDelayed)
190 if (! DANextEventOrTimeout (& ev, HideTimeout))
192 /* timeout ! */
193 LeaveBar () ;
194 continue ; /* restart waiting for an event */
197 else
199 XNextEvent (DADisplay, & ev) ;
201 /* event available, process it */
204 if (ev.type == EnterNotify) /* catch entering any wmmenu window */
206 if (canShowBar) EnterApp () ;
207 canShowBar = true ;
209 else
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 ;
216 LeaveApp () ;
218 else
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 () ;
225 break ;
227 default :
228 DAProcessEvent (& ev) ;
229 break ;
231 else
232 if (ev.xany.window == ButtonBarWindow) switch (ev.type)
234 case ButtonRelease :
235 InvokeBar (ev.xbutton.x, ev.xbutton.y) ;
236 break ;
238 case MotionNotify :
239 if (HighlightImage != 0) /* try to avoid func call */
241 ButtonBar_Highlight (
242 ev.xmotion.x/TileXSize, ev.xmotion.y/TileYSize) ;
244 break ;
246 else
247 if (ev.xany.window == WMFrame && WMFrame != 0) switch (ev.type)
249 case DestroyNotify :
250 case ConfigureNotify :
251 /* find new WMFrame and update bar position */
252 FindWMFrameAndBarPos () ;
253 break ;