2 ===================================================================
3 --- fvwm/events.c (revision 12)
4 +++ fvwm/events.c (revision 13)
7 int last_event_type = 0;
8 Window PressedW = None;
11 /* ---------------------------- local functions ---------------------------- */
12 @@ -1672,6 +1673,23 @@
16 +static void redraw_hover(FvwmWindow* fw, Window w)
21 + for (i = 0; i < NUMBER_OF_TITLE_BUTTONS; i++)
23 + if (w == FW_W_BUTTON(fw, i))
25 + HoverW = FW_W_BUTTON(fw, i);
28 + border_redraw_decorations(fw);
33 /* ---------------------------- event handlers ----------------------------- */
35 void HandleButtonPress(const evh_args_t *ea)
38 ENTER_DBG((stderr, "++++++++ en (%d): fw 0x%08x w 0x%08x sw 0x%08xmode 0x%x detail 0x%x '%s'\n", ++ecount, (int)fw, (int)ewp->window, (int)ewp->subwindow, ewp->mode, ewp->detail, fw?fw->visible_name:"(none)"));
40 + redraw_hover(fw, ewp->window);
43 ewp->window == Scr.Root &&
44 ewp->detail == NotifyInferior && ewp->mode == NotifyNormal)
47 ===================================================================
48 --- fvwm/events.c (revision 12)
49 +++ fvwm/events.c (revision 13)
52 DBUG("HandleLeaveNotify", "Routine Entered");
54 + redraw_hover(fw, te->xcrossing.window);
56 ENTER_DBG((stderr, "-------- ln (%d): fw 0x%08x w 0x%08x sw 0x%08x mode 0x%x detail 0x%x '%s'\n", ++ecount, (int)fw, (int)te->xcrossing.window, (int)te->xcrossing.subwindow, te->xcrossing.mode, te->xcrossing.detail, fw?fw->visible_name:"(none)"));
57 /* Ignore LeaveNotify events while a window is resized or moved as a
58 * wire frame; otherwise the window list may be screwed up. */
60 ===================================================================
61 --- fvwm/fvwm.h (revision 12)
62 +++ fvwm/fvwm.h (revision 13)
64 unsigned buttons_lit : NUMBER_OF_TITLE_BUTTONS;
65 unsigned buttons_inverted : NUMBER_OF_TITLE_BUTTONS;
66 unsigned buttons_toggled : NUMBER_OF_TITLE_BUTTONS;
67 + unsigned buttons_hover : NUMBER_OF_TITLE_BUTTONS;
68 unsigned parts_drawn : 12;
69 unsigned parts_lit : 12;
70 unsigned parts_inverted : 12;
72 ===================================================================
73 --- fvwm/screen.h (revision 12)
74 +++ fvwm/screen.h (revision 13)
85 + BS_ToggledActiveHover,
87 BS_ToggledInactiveDown,
88 + BS_ToggledInactiveHover,
90 BS_MaxButtonStateMask = BS_MaxButtonState - 1,
102 + BS_AllInactiveHover,
103 BS_MaxButtonStateName
107 unsigned use_active_down_buttons : 1;
108 unsigned use_inactive_buttons : 1;
109 unsigned use_inactive_down_buttons : 1;
110 + unsigned use_hover_buttons : 1;
111 } gs; /* global style structure */
114 Index: fvwm/builtins.c
115 ===================================================================
116 --- fvwm/builtins.c (revision 12)
117 +++ fvwm/builtins.c (revision 13)
128 + "ToggledActiveHover",
130 "ToggledInactiveDown",
131 + "ToggledInactiveHover",
135 @@ -109,10 +113,13 @@
145 + "AllInactiveHover",
149 Index: fvwm/borders.c
150 ===================================================================
151 --- fvwm/borders.c (revision 12)
152 +++ fvwm/borders.c (revision 13)
154 /* ---------------------------- imports ------------------------------------ */
156 extern Window PressedW;
157 +extern Window HoverW;
159 /* ---------------------------- included code files ------------------------ */
162 unsigned clear_bmask : NUMBER_OF_TITLE_BUTTONS;
163 unsigned draw_bmask : NUMBER_OF_TITLE_BUTTONS;
164 unsigned max_bmask : NUMBER_OF_TITLE_BUTTONS;
165 + unsigned hover_bmask : NUMBER_OF_TITLE_BUTTONS;
166 ButtonState bstate[NUMBER_OF_TITLE_BUTTONS];
167 unsigned is_title_pressed : 1;
168 unsigned is_title_lit : 1;
171 /* rules to get button state */
172 static ButtonState border_flags_to_button_state(
173 - int is_pressed, int is_lit, int is_toggled)
174 + int is_pressed, int is_lit, int is_toggled, int is_hover)
176 + if (is_lit && is_hover && Scr.gs.use_hover_buttons)
178 + return BS_ActiveHover;
180 if (!is_lit && Scr.gs.use_inactive_buttons)
182 if (is_pressed && Scr.gs.use_inactive_down_buttons)
184 /* check if state changed */
185 old_state = border_flags_to_button_state(
186 (fw->decor_state.parts_inverted & PART_TITLE),
187 - (fw->decor_state.parts_lit & PART_TITLE), 0);
188 + (fw->decor_state.parts_lit & PART_TITLE), 0, 0);
189 if (old_state != td->tbstate.tstate)
191 draw_parts |= PART_TITLE;
193 old_state = border_flags_to_button_state(
194 (fw->decor_state.buttons_inverted & mask),
195 (fw->decor_state.buttons_lit & mask),
196 - (fw->decor_state.buttons_toggled & mask));
197 + (fw->decor_state.buttons_toggled & mask),
198 + (fw->decor_state.buttons_hover & mask));
199 if (old_state != td->tbstate.bstate[i])
201 draw_parts |= PART_BUTTONS;
202 @@ -3993,6 +4000,7 @@
203 fw->decor_state.buttons_inverted = td->tbstate.pressed_bmask;
204 fw->decor_state.buttons_lit = td->tbstate.lit_bmask;
205 fw->decor_state.buttons_toggled = td->tbstate.toggled_bmask;
206 + fw->decor_state.buttons_hover = td->tbstate.hover_bmask;
210 @@ -4259,13 +4267,18 @@
212 tbstate->toggled_bmask |= mask;
214 + if (FW_W_BUTTON(fw, i) == HoverW)
216 + tbstate->hover_bmask |= mask;
218 tbstate->bstate[i] = border_flags_to_button_state(
219 tbstate->pressed_bmask & mask,
220 tbstate->lit_bmask & mask,
221 - tbstate->toggled_bmask & mask);
222 + tbstate->toggled_bmask & mask,
223 + tbstate->hover_bmask & mask);
225 tbstate->tstate = border_flags_to_button_state(
226 - tbstate->is_title_pressed, tbstate->is_title_lit, 0);
227 + tbstate->is_title_pressed, tbstate->is_title_lit, 0, 0);
230 static window_parts border_get_titlebar_descr(
231 @@ -4527,6 +4540,7 @@
232 fw->decor_state.buttons_lit = 0;
233 fw->decor_state.buttons_inverted = 0;
234 fw->decor_state.buttons_toggled = 0;
235 + fw->decor_state.buttons_hover = 0;
238 memset(&td, 0, sizeof(td));
239 @@ -4578,6 +4592,7 @@
240 fw->decor_state.buttons_toggled =
241 (fw->decor_state.buttons_toggled &
242 ~td.tbstate.max_bmask) | td.tbstate.toggled_bmask;
243 + fw->decor_state.buttons_hover &= td.tbstate.hover_bmask;
247 @@ -4668,11 +4683,12 @@
255 is_pressed = (FW_W_TITLE(fw) == PressedW);
256 - bs = border_flags_to_button_state(is_pressed, has_focus, 0);
257 + bs = border_flags_to_button_state(is_pressed, has_focus, 0, 0);
258 if (DFS_USE_BORDER_STYLE(TB_STATE(GetDecor(fw, titlebar))[bs].style))
261 @@ -4685,8 +4701,9 @@
263 is_pressed = (FW_W_BUTTON(fw, i) == PressedW);
264 is_toggled = (is_button_toggled(fw, i) == True);
265 + is_hover = (FW_W_BUTTON(fw, i) == HoverW);
266 bs = border_flags_to_button_state(
267 - is_pressed, (has_focus == True), is_toggled);
268 + is_pressed, (has_focus == True), is_toggled, is_hover);
269 if (DFS_USE_BORDER_STYLE(
270 TB_STATE(GetDecor(fw, buttons[i]))[bs].style))
272 @@ -5147,6 +5164,7 @@
273 DEFAULT_USE_INACTIVE_BUTTONS;
274 Scr.gs.use_inactive_down_buttons =
275 DEFAULT_USE_INACTIVE_DOWN_BUTTONS;
276 + Scr.gs.use_hover_buttons = 0;
280 @@ -5168,6 +5186,12 @@
282 DEFAULT_USE_INACTIVE_DOWN_BUTTONS, True);
284 + else if (StrEquals("hover", token))
286 + Scr.gs.use_hover_buttons = ParseToggleArgument(
292 Scr.gs.use_active_down_buttons =
293 @@ -5176,6 +5200,7 @@
294 DEFAULT_USE_INACTIVE_BUTTONS;
295 Scr.gs.use_inactive_down_buttons =
296 DEFAULT_USE_INACTIVE_DOWN_BUTTONS;
297 + Scr.gs.use_hover_buttons = 0;
298 fvwm_msg(ERR, "cmd_button_state",
299 "Unknown button state %s", token);