wmmenu: Add version 1.2 to repository.
[dockapps.git] / wmmenu / events.c
blob8c44f557d0a688c7de0e074af2d25ea61b4bba45
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"
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 ;
43 long evMask ;
45 /* find window just under root, it is the wm frame icon */
46 /* (or DAWindow itself if none) */
47 root = 0 ;
48 tile = parent = DAWindow ;
49 while (parent != root)
51 tile = parent ;
52 XQueryTree (DADisplay, tile,
53 &root, &parent, &children, &nChildren) ;
54 if (children != NULL) XFree (children) ;
57 /* container actually changed ? */
58 if (WMFrame != tile)
60 #if 0
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) ;
70 #endif
72 /* add events to new container */
73 if (tile != DAWindow)
75 evMask = StructureNotifyMask ; /* move/destroy */
76 if (! ClickOnly)
77 evMask |= EnterWindowMask | LeaveWindowMask ;
78 XSelectInput (DADisplay, tile, evMask) ;
81 WMFrame = tile ;
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 ())
92 Menu_Reload () ;
94 Pixmaps_LoadMenu () ;
95 Pixmaps_LoadTile () ;
97 ButtonBar_Rebuild () ;
98 /* adjust position depending on possible new size */
99 FindWMFrameAndBarPos () ;
102 ButtonBar_Show () ;
103 BarShown = true ;
104 HideBarDelayed = false ;
107 static void LeaveBar (void)
109 ButtonBar_Hide () ;
110 BarShown = false ;
111 HideBarDelayed = false ;
114 static void LeaveApp (void)
116 if (BarShown)
118 ButtonBar_Unhighlight () ;
119 HideBarDelayed = ! ClickOnly ;
123 static void InvokeBar (int x, int y)
125 int h, w ;
126 h = Menu_GetNbRows () ;
127 w = Menu_GetNbColumns () ;
128 x /= TileXSize ;
129 y /= TileYSize ;
130 if (0 <= y && y < h && 0 <= x && x < w)
132 int entry ;
133 entry = y + h*x ;
135 if (entry < Menu_GetNbEntries ())
137 system (Menu_GetEntryCommand (entry)) ;
141 LeaveBar () ;
144 static void PressApp (int button, int state, int x, int y)
146 if (BarShown) LeaveBar () ;
147 else EnterApp () ;
150 extern void Events_SetCallbacks (void)
152 DACallbacks events ;
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 */
170 if (! ClickOnly)
171 ws.event_mask |= EnterWindowMask | LeaveWindowMask ;
172 XChangeWindowAttributes (DADisplay, DAWindow, CWEventMask, & ws) ;
175 extern void Events_Loop (void)
177 XEvent ev ;
178 bool canShowBar = true ;
180 while (true)
182 /* get some event to process */
183 if (HideBarDelayed)
185 if (! DANextEventOrTimeout (& ev, HideTimeout))
187 /* timeout ! */
188 LeaveBar () ;
189 continue ; /* restart waiting for an event */
192 else
194 XNextEvent (DADisplay, & ev) ;
196 /* event available, process it */
199 if (ev.type == EnterNotify) /* catch entering any wmmenu window */
201 if (canShowBar) EnterApp () ;
202 canShowBar = true ;
204 else
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 ;
211 LeaveApp () ;
213 else
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 () ;
220 break ;
222 default :
223 DAProcessEvent (& ev) ;
224 break ;
226 else
227 if (ev.xany.window == ButtonBarWindow) switch (ev.type)
229 case ButtonRelease :
230 InvokeBar (ev.xbutton.x, ev.xbutton.y) ;
231 break ;
233 case MotionNotify :
234 if (HighlightImage != 0) /* try to avoid func call */
236 ButtonBar_Highlight (
237 ev.xmotion.x/TileXSize, ev.xmotion.y/TileYSize) ;
239 break ;
241 else
242 if (ev.xany.window == WMFrame && WMFrame != 0) switch (ev.type)
244 case DestroyNotify :
245 case ConfigureNotify :
246 /* find new WMFrame and update bar position */
247 FindWMFrameAndBarPos () ;
248 break ;