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:
Dana Jansens 2010-01-08 10:45:24 -05:00
parent 73575c10ce
commit 3368b91d54
7 changed files with 80 additions and 65 deletions

View file

@ -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_dockapp(ObDockApp *app, 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 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;
ObMenuFrame *menu = NULL;
ObPrompt *prompt = NULL;
gboolean used;
/* make a copy we can mangle */
ee = *ec;
@ -717,15 +718,13 @@ static void event_process(const XEvent *ec, gpointer data)
}
#endif
if (prompt && event_handle_prompt(prompt, e))
;
else if (e->type == ButtonPress || e->type == ButtonRelease) {
if (e->type == ButtonPress || e->type == ButtonRelease) {
/* If the button press was on some non-root window, or was physically
on the root window, then process it */
if (window != obt_root(ob_screen) ||
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
internal window */
@ -735,13 +734,16 @@ static void event_process(const XEvent *ec, gpointer data)
if ((w = window_find(e->xbutton.subwindow)) &&
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 ||
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
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 ||
e->type == MotionNotify || e->type == KeyPress ||
@ -1966,29 +1968,32 @@ static void event_handle_user_input(ObClient *client, XEvent *e)
/* 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
close the menu and be used */
return;
return TRUE;
}
/* if the keyboard interactive action uses the event then dont
use it for bindings. likewise is moveresize uses the event. */
if (!actions_interactive_input_event(e) && !moveresize_event(e)) {
if (moveresize_in_progress)
/* make further actions work on the client being
moved/resized */
client = moveresize_client;
if (actions_interactive_input_event(e) || moveresize_event(e))
return TRUE;
if (e->type == ButtonPress ||
e->type == ButtonRelease ||
e->type == MotionNotify)
{
/* the frame may not be "visible" but they can still click on it
in the case where it is animating before disappearing */
if (!client || !frame_iconify_animating(client->frame))
mouse_event(client, e);
} else
keyboard_event((focus_cycle_target ? focus_cycle_target :
(client ? client : focus_client)), e);
}
if (moveresize_in_progress)
/* make further actions work on the client being
moved/resized */
client = moveresize_client;
if (e->type == ButtonPress ||
e->type == ButtonRelease ||
e->type == MotionNotify)
{
/* the frame may not be "visible" but they can still click on it
in the case where it is animating before disappearing */
if (!client || !frame_iconify_animating(client->frame))
return mouse_event(client, e);
} else
return keyboard_event((focus_cycle_target ? focus_cycle_target :
(client ? client : focus_client)), e);
return FALSE;
}
static void focus_delay_dest(gpointer data)

View file

@ -204,13 +204,14 @@ gboolean keyboard_process_interactive_grab(const XEvent *e, ObClient **client)
}
#endif
void keyboard_event(ObClient *client, const XEvent *e)
gboolean keyboard_event(ObClient *client, const XEvent *e)
{
KeyBindingTree *p;
gboolean used;
if (e->type == KeyRelease) {
grab_key_passive_count(-1);
return;
return FALSE;
}
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);
keyboard_reset_chains(-1);
return;
return TRUE;
}
used = FALSE;
if (curpos == NULL)
p = keyboard_firstnode;
else
@ -258,9 +260,11 @@ void keyboard_event(ObClient *client, const XEvent *e)
0, OB_FRAME_CONTEXT_NONE, client);
}
break;
used = TRUE;
}
p = p->next_sibling;
}
return used;
}
static void node_rebind(KeyBindingTree *node)

View file

@ -40,7 +40,7 @@ void keyboard_chroot(GList *keylist);
gboolean keyboard_bind(GList *keylist, struct _ObActionsAct *action);
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!
*/
void keyboard_reset_chains(gint break_chroots);

View file

@ -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 guint button = 0, state = 0, lbutton = 0;
static Window lwindow = None;
static gint px, py, pwx = -1, pwy = -1;
gboolean used = FALSE;
ObFrameContext context;
gboolean click = FALSE;
@ -246,10 +247,10 @@ void mouse_event(ObClient *client, XEvent *e)
if (CLIENT_CONTEXT(context, client))
replay_pointer_needed = TRUE;
fire_binding(OB_MOUSE_ACTION_PRESS, context,
client, e->xbutton.state,
e->xbutton.button,
e->xbutton.x_root, e->xbutton.y_root);
used = fire_binding(OB_MOUSE_ACTION_PRESS, context,
client, e->xbutton.state,
e->xbutton.button,
e->xbutton.x_root, e->xbutton.y_root) || used;
/* if the bindings grab the pointer, there won't be a ButtonRelease
event for us */
@ -311,23 +312,23 @@ void mouse_event(ObClient *client, XEvent *e)
state = 0;
ltime = e->xbutton.time;
}
fire_binding(OB_MOUSE_ACTION_RELEASE, context,
client, e->xbutton.state,
e->xbutton.button,
e->xbutton.x_root,
e->xbutton.y_root);
used = fire_binding(OB_MOUSE_ACTION_RELEASE, context,
client, e->xbutton.state,
e->xbutton.button,
e->xbutton.x_root,
e->xbutton.y_root) || used;
if (click)
fire_binding(OB_MOUSE_ACTION_CLICK, context,
client, e->xbutton.state,
e->xbutton.button,
e->xbutton.x_root,
e->xbutton.y_root);
used = fire_binding(OB_MOUSE_ACTION_CLICK, context,
client, e->xbutton.state,
e->xbutton.button,
e->xbutton.x_root,
e->xbutton.y_root) || used;
if (dclick)
fire_binding(OB_MOUSE_ACTION_DOUBLE_CLICK, context,
client, e->xbutton.state,
e->xbutton.button,
e->xbutton.x_root,
e->xbutton.y_root);
used = fire_binding(OB_MOUSE_ACTION_DOUBLE_CLICK, context,
client, e->xbutton.state,
e->xbutton.button,
e->xbutton.x_root,
e->xbutton.y_root) || used;
break;
case MotionNotify:
@ -347,8 +348,8 @@ void mouse_event(ObClient *client, XEvent *e)
context == OB_FRAME_CONTEXT_CLOSE)
break;
fire_binding(OB_MOUSE_ACTION_MOTION, context,
client, state, button, px, py);
used = fire_binding(OB_MOUSE_ACTION_MOTION, context,
client, state, button, px, py);
button = 0;
state = 0;
}
@ -358,6 +359,7 @@ void mouse_event(ObClient *client, XEvent *e)
default:
g_assert_not_reached();
}
return used;
}
gboolean mouse_bind(const gchar *buttonstr, const gchar *contextstr,

View file

@ -33,7 +33,7 @@ gboolean mouse_bind(const gchar *buttonstr, const gchar *contextstr,
ObMouseAction mact, struct _ObActionsAct *action);
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);

View file

@ -411,10 +411,10 @@ static void render_button(ObPrompt *self, ObPromptElement *e)
{
RrAppearance *a;
if (e->pressed && self->focus == e) a = prompt_a_pfocus;
else if (self->focus == e) a = prompt_a_focus;
else if (e->pressed) a = prompt_a_press;
else a = prompt_a_button;
if (e->hover && self->focus == e) a = prompt_a_pfocus;
else if (self->focus == e) a = prompt_a_focus;
else if (e->pressed) a = prompt_a_press;
else a = prompt_a_button;
a->surface.parent = prompt_a_bg;
a->surface.parentx = e->x;
@ -587,25 +587,28 @@ gboolean prompt_mouse_event(ObPrompt *self, XEvent *e)
oldfocus = self->focus;
but->pressed = TRUE;
but->pressed = but->hover = TRUE;
self->focus = but;
if (oldfocus != but) render_button(self, oldfocus);
render_button(self, but);
}
else if (e->type == ButtonRelease) {
if (but->pressed)
if (but->hover)
prompt_run_callback(self, but->result);
but->pressed = FALSE;
}
else if (e->type == MotionNotify) {
gboolean press;
if (but->pressed) {
gboolean hover;
press = (e->xmotion.x >= 0 && e->xmotion.y >= 0 &&
e->xmotion.x < but->width && e->xmotion.y < but->height);
hover = (e->xmotion.x >= 0 && e->xmotion.y >= 0 &&
e->xmotion.x < but->width && e->xmotion.y < but->height);
if (press != but->pressed) {
but->pressed = press;
render_button(self, but);
if (hover != but->hover) {
but->hover = hover;
render_button(self, but);
}
}
}
return TRUE;

View file

@ -38,6 +38,7 @@ struct _ObPromptElement {
gint x, y, width, height;
gboolean pressed;
gboolean hover;
gint result;
};