Add missing libraries to examples' Makefiles
[dockapps.git] / wmmenu / events.c
blob6eaf904932fa6c3f7e10a5e7390fbc2dd844e50d
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 <libdockapp/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 (void) button;
152 (void) state;
153 (void) x;
154 (void) y;
155 if (BarShown) LeaveBar () ;
156 else EnterApp () ;
159 extern void Events_SetCallbacks (void)
161 DACallbacks events ;
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 */
179 if (! ClickOnly)
180 ws.event_mask |= EnterWindowMask | LeaveWindowMask ;
181 XChangeWindowAttributes (DADisplay, DAWindow, CWEventMask, & ws) ;
184 extern void Events_Loop (void)
186 XEvent ev ;
187 bool canShowBar = true ;
189 while (true)
191 /* get some event to process */
192 if (HideBarDelayed)
194 if (! DANextEventOrTimeout (& ev, HideTimeout))
196 /* timeout ! */
197 LeaveBar () ;
198 continue ; /* restart waiting for an event */
201 else
203 XNextEvent (DADisplay, & ev) ;
205 /* event available, process it */
208 if (ev.type == EnterNotify) /* catch entering any wmmenu window */
210 if (canShowBar) EnterApp () ;
211 canShowBar = true ;
213 else
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 ;
220 LeaveApp () ;
222 else
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 () ;
229 break ;
231 default :
232 DAProcessEvent (& ev) ;
233 break ;
235 else
236 if (ev.xany.window == ButtonBarWindow) switch (ev.type)
238 case ButtonRelease :
239 InvokeBar (ev.xbutton.x, ev.xbutton.y) ;
240 break ;
242 case MotionNotify :
243 if (HighlightImage != 0) /* try to avoid func call */
245 ButtonBar_Highlight (
246 ev.xmotion.x/TileXSize, ev.xmotion.y/TileYSize) ;
248 break ;
250 else
251 if (ev.xany.window == WMFrame && WMFrame != 0) switch (ev.type)
253 case DestroyNotify :
254 case ConfigureNotify :
255 /* find new WMFrame and update bar position */
256 FindWMFrameAndBarPos () ;
257 break ;