Don't handle input events on prompts if they should be used for a binding/menu instead.
Also, be more careful about making the prompt buttons look pressed, don't make them pressed from a motion notify event if they didnt first handle the press.
This commit is contained in:
parent
73575c10ce
commit
3368b91d54
7 changed files with 80 additions and 65 deletions
|
@ -90,7 +90,7 @@ static gboolean event_handle_prompt(ObPrompt *p, XEvent *e);
|
||||||
static void event_handle_dock(ObDock *s, XEvent *e);
|
static void event_handle_dock(ObDock *s, XEvent *e);
|
||||||
static void event_handle_dockapp(ObDockApp *app, XEvent *e);
|
static void event_handle_dockapp(ObDockApp *app, XEvent *e);
|
||||||
static void event_handle_client(ObClient *c, XEvent *e);
|
static void event_handle_client(ObClient *c, XEvent *e);
|
||||||
static void event_handle_user_input(ObClient *client, XEvent *e);
|
static gboolean event_handle_user_input(ObClient *client, XEvent *e);
|
||||||
static gboolean is_enter_focus_event_ignored(gulong serial);
|
static gboolean is_enter_focus_event_ignored(gulong serial);
|
||||||
static void event_ignore_enter_range(gulong start, gulong end);
|
static void event_ignore_enter_range(gulong start, gulong end);
|
||||||
|
|
||||||
|
@ -472,6 +472,7 @@ static void event_process(const XEvent *ec, gpointer data)
|
||||||
ObWindow *obwin = NULL;
|
ObWindow *obwin = NULL;
|
||||||
ObMenuFrame *menu = NULL;
|
ObMenuFrame *menu = NULL;
|
||||||
ObPrompt *prompt = NULL;
|
ObPrompt *prompt = NULL;
|
||||||
|
gboolean used;
|
||||||
|
|
||||||
/* make a copy we can mangle */
|
/* make a copy we can mangle */
|
||||||
ee = *ec;
|
ee = *ec;
|
||||||
|
@ -717,15 +718,13 @@ static void event_process(const XEvent *ec, gpointer data)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (prompt && event_handle_prompt(prompt, e))
|
if (e->type == ButtonPress || e->type == ButtonRelease) {
|
||||||
;
|
|
||||||
else if (e->type == ButtonPress || e->type == ButtonRelease) {
|
|
||||||
/* If the button press was on some non-root window, or was physically
|
/* If the button press was on some non-root window, or was physically
|
||||||
on the root window, then process it */
|
on the root window, then process it */
|
||||||
if (window != obt_root(ob_screen) ||
|
if (window != obt_root(ob_screen) ||
|
||||||
e->xbutton.subwindow == None)
|
e->xbutton.subwindow == None)
|
||||||
{
|
{
|
||||||
event_handle_user_input(client, e);
|
used = event_handle_user_input(client, e);
|
||||||
}
|
}
|
||||||
/* Otherwise only process it if it was physically on an openbox
|
/* Otherwise only process it if it was physically on an openbox
|
||||||
internal window */
|
internal window */
|
||||||
|
@ -735,13 +734,16 @@ static void event_process(const XEvent *ec, gpointer data)
|
||||||
if ((w = window_find(e->xbutton.subwindow)) &&
|
if ((w = window_find(e->xbutton.subwindow)) &&
|
||||||
WINDOW_IS_INTERNAL(w))
|
WINDOW_IS_INTERNAL(w))
|
||||||
{
|
{
|
||||||
event_handle_user_input(client, e);
|
used = event_handle_user_input(client, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (e->type == KeyPress || e->type == KeyRelease ||
|
else if (e->type == KeyPress || e->type == KeyRelease ||
|
||||||
e->type == MotionNotify)
|
e->type == MotionNotify)
|
||||||
event_handle_user_input(client, e);
|
used = event_handle_user_input(client, e);
|
||||||
|
|
||||||
|
if (prompt && !used)
|
||||||
|
used = event_handle_prompt(prompt, e);
|
||||||
|
|
||||||
/* if something happens and it's not from an XEvent, then we don't know
|
/* if something happens and it's not from an XEvent, then we don't know
|
||||||
the time */
|
the time */
|
||||||
|
@ -1955,7 +1957,7 @@ static void event_handle_menu(ObMenuFrame *frame, XEvent *ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void event_handle_user_input(ObClient *client, XEvent *e)
|
static gboolean event_handle_user_input(ObClient *client, XEvent *e)
|
||||||
{
|
{
|
||||||
g_assert(e->type == ButtonPress || e->type == ButtonRelease ||
|
g_assert(e->type == ButtonPress || e->type == ButtonRelease ||
|
||||||
e->type == MotionNotify || e->type == KeyPress ||
|
e->type == MotionNotify || e->type == KeyPress ||
|
||||||
|
@ -1966,12 +1968,14 @@ static void event_handle_user_input(ObClient *client, XEvent *e)
|
||||||
/* don't use the event if the menu used it, but if the menu
|
/* don't use the event if the menu used it, but if the menu
|
||||||
didn't use it and it's a keypress that is bound, it will
|
didn't use it and it's a keypress that is bound, it will
|
||||||
close the menu and be used */
|
close the menu and be used */
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if the keyboard interactive action uses the event then dont
|
/* if the keyboard interactive action uses the event then dont
|
||||||
use it for bindings. likewise is moveresize uses the event. */
|
use it for bindings. likewise is moveresize uses the event. */
|
||||||
if (!actions_interactive_input_event(e) && !moveresize_event(e)) {
|
if (actions_interactive_input_event(e) || moveresize_event(e))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
if (moveresize_in_progress)
|
if (moveresize_in_progress)
|
||||||
/* make further actions work on the client being
|
/* make further actions work on the client being
|
||||||
moved/resized */
|
moved/resized */
|
||||||
|
@ -1984,11 +1988,12 @@ static void event_handle_user_input(ObClient *client, XEvent *e)
|
||||||
/* the frame may not be "visible" but they can still click on it
|
/* the frame may not be "visible" but they can still click on it
|
||||||
in the case where it is animating before disappearing */
|
in the case where it is animating before disappearing */
|
||||||
if (!client || !frame_iconify_animating(client->frame))
|
if (!client || !frame_iconify_animating(client->frame))
|
||||||
mouse_event(client, e);
|
return mouse_event(client, e);
|
||||||
} else
|
} else
|
||||||
keyboard_event((focus_cycle_target ? focus_cycle_target :
|
return keyboard_event((focus_cycle_target ? focus_cycle_target :
|
||||||
(client ? client : focus_client)), e);
|
(client ? client : focus_client)), e);
|
||||||
}
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void focus_delay_dest(gpointer data)
|
static void focus_delay_dest(gpointer data)
|
||||||
|
|
|
@ -204,13 +204,14 @@ gboolean keyboard_process_interactive_grab(const XEvent *e, ObClient **client)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void keyboard_event(ObClient *client, const XEvent *e)
|
gboolean keyboard_event(ObClient *client, const XEvent *e)
|
||||||
{
|
{
|
||||||
KeyBindingTree *p;
|
KeyBindingTree *p;
|
||||||
|
gboolean used;
|
||||||
|
|
||||||
if (e->type == KeyRelease) {
|
if (e->type == KeyRelease) {
|
||||||
grab_key_passive_count(-1);
|
grab_key_passive_count(-1);
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_assert(e->type == KeyPress);
|
g_assert(e->type == KeyPress);
|
||||||
|
@ -221,9 +222,10 @@ void keyboard_event(ObClient *client, const XEvent *e)
|
||||||
{
|
{
|
||||||
obt_main_loop_timeout_remove(ob_main_loop, chain_timeout);
|
obt_main_loop_timeout_remove(ob_main_loop, chain_timeout);
|
||||||
keyboard_reset_chains(-1);
|
keyboard_reset_chains(-1);
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
used = FALSE;
|
||||||
if (curpos == NULL)
|
if (curpos == NULL)
|
||||||
p = keyboard_firstnode;
|
p = keyboard_firstnode;
|
||||||
else
|
else
|
||||||
|
@ -258,9 +260,11 @@ void keyboard_event(ObClient *client, const XEvent *e)
|
||||||
0, OB_FRAME_CONTEXT_NONE, client);
|
0, OB_FRAME_CONTEXT_NONE, client);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
used = TRUE;
|
||||||
}
|
}
|
||||||
p = p->next_sibling;
|
p = p->next_sibling;
|
||||||
}
|
}
|
||||||
|
return used;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void node_rebind(KeyBindingTree *node)
|
static void node_rebind(KeyBindingTree *node)
|
||||||
|
|
|
@ -40,7 +40,7 @@ void keyboard_chroot(GList *keylist);
|
||||||
gboolean keyboard_bind(GList *keylist, struct _ObActionsAct *action);
|
gboolean keyboard_bind(GList *keylist, struct _ObActionsAct *action);
|
||||||
void keyboard_unbind_all(void);
|
void keyboard_unbind_all(void);
|
||||||
|
|
||||||
void keyboard_event(struct _ObClient *client, const XEvent *e);
|
gboolean keyboard_event(struct _ObClient *client, const XEvent *e);
|
||||||
/*! @param break_chroots how many chroots to break. -1 means to break them ALL!
|
/*! @param break_chroots how many chroots to break. -1 means to break them ALL!
|
||||||
*/
|
*/
|
||||||
void keyboard_reset_chains(gint break_chroots);
|
void keyboard_reset_chains(gint break_chroots);
|
||||||
|
|
|
@ -205,12 +205,13 @@ void mouse_replay_pointer(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mouse_event(ObClient *client, XEvent *e)
|
gboolean mouse_event(ObClient *client, XEvent *e)
|
||||||
{
|
{
|
||||||
static Time ltime;
|
static Time ltime;
|
||||||
static guint button = 0, state = 0, lbutton = 0;
|
static guint button = 0, state = 0, lbutton = 0;
|
||||||
static Window lwindow = None;
|
static Window lwindow = None;
|
||||||
static gint px, py, pwx = -1, pwy = -1;
|
static gint px, py, pwx = -1, pwy = -1;
|
||||||
|
gboolean used = FALSE;
|
||||||
|
|
||||||
ObFrameContext context;
|
ObFrameContext context;
|
||||||
gboolean click = FALSE;
|
gboolean click = FALSE;
|
||||||
|
@ -246,10 +247,10 @@ void mouse_event(ObClient *client, XEvent *e)
|
||||||
if (CLIENT_CONTEXT(context, client))
|
if (CLIENT_CONTEXT(context, client))
|
||||||
replay_pointer_needed = TRUE;
|
replay_pointer_needed = TRUE;
|
||||||
|
|
||||||
fire_binding(OB_MOUSE_ACTION_PRESS, context,
|
used = fire_binding(OB_MOUSE_ACTION_PRESS, context,
|
||||||
client, e->xbutton.state,
|
client, e->xbutton.state,
|
||||||
e->xbutton.button,
|
e->xbutton.button,
|
||||||
e->xbutton.x_root, e->xbutton.y_root);
|
e->xbutton.x_root, e->xbutton.y_root) || used;
|
||||||
|
|
||||||
/* if the bindings grab the pointer, there won't be a ButtonRelease
|
/* if the bindings grab the pointer, there won't be a ButtonRelease
|
||||||
event for us */
|
event for us */
|
||||||
|
@ -311,23 +312,23 @@ void mouse_event(ObClient *client, XEvent *e)
|
||||||
state = 0;
|
state = 0;
|
||||||
ltime = e->xbutton.time;
|
ltime = e->xbutton.time;
|
||||||
}
|
}
|
||||||
fire_binding(OB_MOUSE_ACTION_RELEASE, context,
|
used = fire_binding(OB_MOUSE_ACTION_RELEASE, context,
|
||||||
client, e->xbutton.state,
|
client, e->xbutton.state,
|
||||||
e->xbutton.button,
|
e->xbutton.button,
|
||||||
e->xbutton.x_root,
|
e->xbutton.x_root,
|
||||||
e->xbutton.y_root);
|
e->xbutton.y_root) || used;
|
||||||
if (click)
|
if (click)
|
||||||
fire_binding(OB_MOUSE_ACTION_CLICK, context,
|
used = fire_binding(OB_MOUSE_ACTION_CLICK, context,
|
||||||
client, e->xbutton.state,
|
client, e->xbutton.state,
|
||||||
e->xbutton.button,
|
e->xbutton.button,
|
||||||
e->xbutton.x_root,
|
e->xbutton.x_root,
|
||||||
e->xbutton.y_root);
|
e->xbutton.y_root) || used;
|
||||||
if (dclick)
|
if (dclick)
|
||||||
fire_binding(OB_MOUSE_ACTION_DOUBLE_CLICK, context,
|
used = fire_binding(OB_MOUSE_ACTION_DOUBLE_CLICK, context,
|
||||||
client, e->xbutton.state,
|
client, e->xbutton.state,
|
||||||
e->xbutton.button,
|
e->xbutton.button,
|
||||||
e->xbutton.x_root,
|
e->xbutton.x_root,
|
||||||
e->xbutton.y_root);
|
e->xbutton.y_root) || used;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MotionNotify:
|
case MotionNotify:
|
||||||
|
@ -347,7 +348,7 @@ void mouse_event(ObClient *client, XEvent *e)
|
||||||
context == OB_FRAME_CONTEXT_CLOSE)
|
context == OB_FRAME_CONTEXT_CLOSE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
fire_binding(OB_MOUSE_ACTION_MOTION, context,
|
used = fire_binding(OB_MOUSE_ACTION_MOTION, context,
|
||||||
client, state, button, px, py);
|
client, state, button, px, py);
|
||||||
button = 0;
|
button = 0;
|
||||||
state = 0;
|
state = 0;
|
||||||
|
@ -358,6 +359,7 @@ void mouse_event(ObClient *client, XEvent *e)
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
return used;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean mouse_bind(const gchar *buttonstr, const gchar *contextstr,
|
gboolean mouse_bind(const gchar *buttonstr, const gchar *contextstr,
|
||||||
|
|
|
@ -33,7 +33,7 @@ gboolean mouse_bind(const gchar *buttonstr, const gchar *contextstr,
|
||||||
ObMouseAction mact, struct _ObActionsAct *action);
|
ObMouseAction mact, struct _ObActionsAct *action);
|
||||||
void mouse_unbind_all(void);
|
void mouse_unbind_all(void);
|
||||||
|
|
||||||
void mouse_event(struct _ObClient *client, XEvent *e);
|
gboolean mouse_event(struct _ObClient *client, XEvent *e);
|
||||||
|
|
||||||
void mouse_grab_for_client(struct _ObClient *client, gboolean grab);
|
void mouse_grab_for_client(struct _ObClient *client, gboolean grab);
|
||||||
|
|
||||||
|
|
|
@ -411,7 +411,7 @@ static void render_button(ObPrompt *self, ObPromptElement *e)
|
||||||
{
|
{
|
||||||
RrAppearance *a;
|
RrAppearance *a;
|
||||||
|
|
||||||
if (e->pressed && self->focus == e) a = prompt_a_pfocus;
|
if (e->hover && self->focus == e) a = prompt_a_pfocus;
|
||||||
else if (self->focus == e) a = prompt_a_focus;
|
else if (self->focus == e) a = prompt_a_focus;
|
||||||
else if (e->pressed) a = prompt_a_press;
|
else if (e->pressed) a = prompt_a_press;
|
||||||
else a = prompt_a_button;
|
else a = prompt_a_button;
|
||||||
|
@ -587,27 +587,30 @@ gboolean prompt_mouse_event(ObPrompt *self, XEvent *e)
|
||||||
|
|
||||||
oldfocus = self->focus;
|
oldfocus = self->focus;
|
||||||
|
|
||||||
but->pressed = TRUE;
|
but->pressed = but->hover = TRUE;
|
||||||
self->focus = but;
|
self->focus = but;
|
||||||
|
|
||||||
if (oldfocus != but) render_button(self, oldfocus);
|
if (oldfocus != but) render_button(self, oldfocus);
|
||||||
render_button(self, but);
|
render_button(self, but);
|
||||||
}
|
}
|
||||||
else if (e->type == ButtonRelease) {
|
else if (e->type == ButtonRelease) {
|
||||||
if (but->pressed)
|
if (but->hover)
|
||||||
prompt_run_callback(self, but->result);
|
prompt_run_callback(self, but->result);
|
||||||
|
but->pressed = FALSE;
|
||||||
}
|
}
|
||||||
else if (e->type == MotionNotify) {
|
else if (e->type == MotionNotify) {
|
||||||
gboolean press;
|
if (but->pressed) {
|
||||||
|
gboolean hover;
|
||||||
|
|
||||||
press = (e->xmotion.x >= 0 && e->xmotion.y >= 0 &&
|
hover = (e->xmotion.x >= 0 && e->xmotion.y >= 0 &&
|
||||||
e->xmotion.x < but->width && e->xmotion.y < but->height);
|
e->xmotion.x < but->width && e->xmotion.y < but->height);
|
||||||
|
|
||||||
if (press != but->pressed) {
|
if (hover != but->hover) {
|
||||||
but->pressed = press;
|
but->hover = hover;
|
||||||
render_button(self, but);
|
render_button(self, but);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ struct _ObPromptElement {
|
||||||
|
|
||||||
gint x, y, width, height;
|
gint x, y, width, height;
|
||||||
gboolean pressed;
|
gboolean pressed;
|
||||||
|
gboolean hover;
|
||||||
gint result;
|
gint result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue