#include "debug.h"
#include "client.h"
#include "focus.h"
+#include "focus_cycle.h"
#include "moveresize.h"
#include "menu.h"
#include "prop.h"
#include <glib.h>
-inline void client_action_start(union ActionData *data)
+static void client_action_start(union ActionData *data)
{
- if (config_focus_follow)
- if (data->any.context != OB_FRAME_CONTEXT_CLIENT && !data->any.button)
- grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
}
-inline void client_action_end(union ActionData *data)
+static void client_action_end(union ActionData *data)
{
if (config_focus_follow)
if (data->any.context != OB_FRAME_CONTEXT_CLIENT) {
- if (!data->any.button) {
- ungrab_pointer();
+ if (!data->any.button && data->any.c) {
+ event_ignore_all_queued_enters();
} else {
ObClient *c;
event will come as a GrabNotify which is ignored, so this
makes a fake enter event
*/
- if ((c = client_under_pointer()))
+ if ((c = client_under_pointer()) && c != data->any.c)
event_enter_client(c);
}
}
void setup_action_desktop(ObAction **a, ObUserAction uact)
{
+/*
(*a)->data.desktop.inter.any.interactive = FALSE;
+*/
}
void setup_action_desktop_prev(ObAction **a, ObUserAction uact)
if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
act->data.desktop.desk = parse_int(doc, n);
if (act->data.desktop.desk > 0) act->data.desktop.desk--;
+/*
if ((n = parse_find_node("dialog", node->xmlChildrenNode)))
act->data.desktop.inter.any.interactive =
parse_bool(doc, n);
+*/
} else if (act->func == action_send_to_desktop) {
if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
act->data.sendto.desk = parse_int(doc, n);
/* XXX UGLY HACK race with motion event starting a move and the
button release gettnig processed first. answer: don't queue
- moveresize starts. UGLY HACK XXX */
+ moveresize starts. UGLY HACK XXX
+
+ XXX ALSO don't queue showmenu events, because on button press
+ events we need to know if a mouse grab is going to take place,
+ and set the button to 0, so that later motion events don't think
+ that a drag is going on. since showmenu grabs the pointer..
+ */
if (a->data.any.interactive || a->func == action_move ||
- a->func == action_resize)
+ a->func == action_resize || a->func == action_showmenu)
{
/* interactive actions are not queued */
a->func(&a->data);
- } else if (c &&
- (context == OB_FRAME_CONTEXT_CLIENT ||
- (c->type == OB_CLIENT_TYPE_DESKTOP &&
- context == OB_FRAME_CONTEXT_DESKTOP)) &&
- (a->func == action_focus ||
- a->func == action_activate ||
- a->func == action_showmenu))
+ } else if (a->func == action_focus ||
+ a->func == action_activate ||
+ a->func == action_showmenu)
{
/* XXX MORE UGLY HACK
actions from clicks on client windows are NOT queued.
pointer. ugh.
also with the menus, there is a race going on. if the
- desktop wants to pop up a menu, and we do to, we send them
+ desktop wants to pop up a menu, and we do too, we send them
the button before we pop up the menu, so they pop up their
menu first. but not always. if we pop up our menu before
sending them the button press, then the result is
deterministic. yay.
+
+ XXX further more. focus actions are not queued at all,
+ because if you bind focus->showmenu, the menu will get
+ hidden to do the focusing
*/
a->func(&a->data);
} else
GError *e = NULL;
gchar *cmd, **argv = 0;
if (data->execute.path) {
- /* Ungrab the keyboard before running the action.
-
- If there is an interactive action going on, then cancel it to
- release the keyboard. If not, then call XUngrabKeyboard().
-
- We call XUngrabKeyboard because a key press causes a passive
- grab on the keyboard, and so if program we are executing wants to
- grab the keyboard, it will fail if the button is still held down
- (which is likely).
-
- Use the X function not out own, because we're not considering
- a grab to be in place at all so our function won't try ungrab
- anything.
- */
- if (keyboard_interactively_grabbed())
- keyboard_interactive_cancel();
- else
- XUngrabKeyboard(ob_display, data->any.time);
-
cmd = g_filename_from_utf8(data->execute.path, -1, NULL, NULL, NULL);
if (cmd) {
+ /* If there is a keyboard grab going on then we need to cancel
+ it so the application can grab things */
+ event_cancel_all_key_grabs();
+
if (!g_shell_parse_argv (cmd, NULL, &argv, &e)) {
g_message(_("Failed to execute '%s': %s"),
cmd, e->message);
void action_unfocus (union ActionData *data)
{
if (data->client.any.c == focus_client)
- focus_fallback(TRUE);
+ focus_fallback(FALSE, FALSE);
}
void action_iconify(union ActionData *data)
if (data->sendto.desk < screen_num_desktops ||
data->sendto.desk == DESKTOP_ALL) {
client_set_desktop(c, data->sendto.desk, data->sendto.follow);
- if (data->sendto.follow)
+ if (data->sendto.follow && data->sendto.desk != screen_desktop)
screen_set_desktop(data->sendto.desk, TRUE);
}
}
void action_desktop(union ActionData *data)
{
- if (!data->inter.any.interactive ||
- (!data->inter.cancel && !data->inter.final))
+ /* XXX add the interactive/dialog option back again once the dialog
+ has been made to not use grabs */
+ if (data->desktop.desk < screen_num_desktops ||
+ data->desktop.desk == DESKTOP_ALL)
{
- if (data->desktop.desk < screen_num_desktops ||
- data->desktop.desk == DESKTOP_ALL)
- {
- screen_set_desktop(data->desktop.desk, TRUE);
- if (data->inter.any.interactive)
- screen_desktop_popup(data->desktop.desk, TRUE);
- }
- } else
- screen_desktop_popup(0, FALSE);
+ screen_set_desktop(data->desktop.desk, TRUE);
+ if (data->inter.any.interactive)
+ screen_desktop_popup(data->desktop.desk, TRUE);
+ }
}
void action_desktop_dir(union ActionData *data)
if (!data->sendtodir.inter.any.interactive ||
(data->sendtodir.inter.final && !data->sendtodir.inter.cancel))
{
- if (d != screen_desktop) screen_set_desktop(d, TRUE);
+ if (d != screen_desktop)
+ screen_set_desktop(d, TRUE);
}
}