#include "actions.h"
#include "gettext.h"
#include "grab.h"
+#include "screen.h"
static void actions_definition_ref(ObActionsDefinition *def);
static void actions_definition_unref(ObActionsDefinition *def);
void actions_startup(gboolean reconfig)
{
if (reconfig) return;
-
-
}
void actions_shutdown(gboolean reconfig)
{
+ actions_interactive_cancel_act();
+
if (reconfig) return;
/* free all the registered actions */
{
GSList *it;
+ /* Don't allow saving the initial state when running things from the
+ menu */
+ if (uact == OB_USER_ACTION_MENU_SELECTION)
+ state = 0;
+ /* If x and y are < 0 then use the current pointer position */
+ if (x < 0 && y < 0)
+ screen_pointer_pos(&x, &y);
+
for (it = acts; it; it = g_slist_next(it)) {
ObActionsData data;
ObActionsAct *act = it->data;
#include "openbox.h"
#include "menu.h"
#include "menuframe.h"
-#include "action.h"
#include "screen.h"
#include "client.h"
#include "focus.h"
ObMenu *menu = frame->menu;
ObMenuEntry *e;
GList *it;
- gint i;
guint desktop;
menu_clear_entries(menu);
gboolean onlyiconic = TRUE;
menu_add_separator(menu, -1, screen_desktop_names[desktop]);
- for (it = focus_order, i = 0; it; it = g_list_next(it), ++i) {
+ for (it = focus_order; it; it = g_list_next(it)) {
ObClient *c = it->data;
if (client_normal(c) && (!c->skip_taskbar || c->iconic) &&
(c->desktop == desktop || c->desktop == DESKTOP_ALL))
{
- GSList *acts = NULL;
- ObAction* act;
const ObClientIcon *icon;
empty = FALSE;
- act = action_from_string("Activate",
- OB_USER_ACTION_MENU_SELECTION);
- act->data.activate.any.c = c;
- acts = g_slist_append(acts, act);
- act = action_from_string("Desktop",
- OB_USER_ACTION_MENU_SELECTION);
- act->data.desktop.desk = desktop;
- acts = g_slist_append(acts, act);
-
if (c->iconic) {
gchar *title = g_strdup_printf("(%s)", c->icon_title);
- e = menu_add_normal(menu, i, title, acts, FALSE);
+ e = menu_add_normal(menu, -1, title, NULL, FALSE);
g_free(title);
} else {
onlyiconic = FALSE;
- e = menu_add_normal(menu, i, c->title, acts, FALSE);
+ e = menu_add_normal(menu, -1, c->title, NULL, FALSE);
}
if (config_menu_client_list_icons
e->data.normal.icon_alpha =
c->iconic ? OB_ICONIC_ALPHA : 0xff;
}
+
+ e->data.normal.data = c;
}
}
if (empty || onlyiconic) {
+ ObMenuEntry *e;
+
/* no entries or only iconified windows, so add a
* way to go to this desktop without uniconifying a window */
if (!empty)
menu_add_separator(menu, -1, NULL);
- GSList *acts = NULL;
- ObAction* act;
- ObMenuEntry *e;
-
- act = action_from_string("Desktop", OB_USER_ACTION_MENU_SELECTION);
- act->data.desktop.desk = desktop;
- acts = g_slist_append(acts, act);
- e = menu_add_normal(menu, 0, _("Go there..."), acts, TRUE);
+ e = menu_add_normal(menu, desktop, _("Go there..."), NULL, TRUE);
if (desktop == screen_desktop)
e->data.normal.enabled = FALSE;
}
return TRUE; /* always show the menu */
}
-/* executes it using the client in the actions, since we set that
- when we make the actions! */
static void menu_execute(ObMenuEntry *self, ObMenuFrame *f,
ObClient *c, guint state, gpointer data,
Time time)
{
- ObAction *a;
-
- if (self->data.normal.actions) {
- a = self->data.normal.actions->data;
- action_run(self->data.normal.actions, a->data.any.c, state, time);
+ if (self->id == -1) {
+ if (self->data.normal.data) /* it's set to NULL if its destroyed */
+ client_activate(self->data.normal.data, FALSE, TRUE);
}
+ else
+ screen_set_desktop(self->id, TRUE);
}
static void client_dest(ObClient *client, gpointer data)
for (eit = combined_menu->entries; eit; eit = g_list_next(eit)) {
ObMenuEntry *meit = eit->data;
if (meit->type == OB_MENU_ENTRY_TYPE_NORMAL &&
- meit->data.normal.actions)
+ meit->data.normal.data == client)
{
- ObAction *a = meit->data.normal.actions->data;
- ObClient *c = a->data.any.c;
- if (c == client)
- a->data.any.c = NULL;
+ meit->data.normal.data = NULL;
}
}
}
#include "openbox.h"
#include "menu.h"
#include "menuframe.h"
-#include "action.h"
#include "screen.h"
#include "client.h"
#include "focus.h"
ObMenu *menu = frame->menu;
DesktopData *d = data;
GList *it;
- gint i;
gboolean empty = TRUE;
gboolean onlyiconic = TRUE;
menu_clear_entries(menu);
- for (it = focus_order, i = 0; it; it = g_list_next(it), ++i) {
+ for (it = focus_order; it; it = g_list_next(it)) {
ObClient *c = it->data;
if (client_normal(c) && (!c->skip_taskbar || c->iconic) &&
(c->desktop == d->desktop || c->desktop == DESKTOP_ALL))
{
- GSList *acts = NULL;
- ObAction* act;
ObMenuEntry *e;
const ObClientIcon *icon;
empty = FALSE;
- act = action_from_string("Activate",
- OB_USER_ACTION_MENU_SELECTION);
- act->data.activate.any.c = c;
- acts = g_slist_append(acts, act);
- act = action_from_string("Desktop",
- OB_USER_ACTION_MENU_SELECTION);
- act->data.desktop.desk = d->desktop;
- acts = g_slist_append(acts, act);
-
if (c->iconic) {
gchar *title = g_strdup_printf("(%s)", c->icon_title);
- e = menu_add_normal(menu, i, title, acts, FALSE);
+ e = menu_add_normal(menu, -1, title, NULL, FALSE);
g_free(title);
} else {
onlyiconic = FALSE;
- e = menu_add_normal(menu, i, c->title, acts, FALSE);
+ e = menu_add_normal(menu, -1, c->title, NULL, FALSE);
}
if (config_menu_client_list_icons
e->data.normal.icon_data = icon->data;
e->data.normal.icon_alpha = c->iconic ? OB_ICONIC_ALPHA : 0xff;
}
+
+ e->data.normal.data = c;
}
}
if (empty || onlyiconic) {
+ ObMenuEntry *e;
+
/* no entries or only iconified windows, so add a
* way to go to this desktop without uniconifying a window */
if (!empty)
menu_add_separator(menu, -1, NULL);
- GSList *acts = NULL;
- ObAction* act;
- ObMenuEntry *e;
-
- act = action_from_string("Desktop", OB_USER_ACTION_MENU_SELECTION);
- act->data.desktop.desk = d->desktop;
- acts = g_slist_append(acts, act);
- e = menu_add_normal(menu, 0, _("Go there..."), acts, TRUE);
+ e = menu_add_normal(menu, d->desktop, _("Go there..."), NULL, TRUE);
if (d->desktop == screen_desktop)
e->data.normal.enabled = FALSE;
}
return TRUE; /* always show */
}
-/* executes it using the client in the actions, since we set that
- when we make the actions! */
static void desk_menu_execute(ObMenuEntry *self, ObMenuFrame *f,
ObClient *c, guint state, gpointer data,
Time time)
{
- ObAction *a;
-
- if (self->data.normal.actions) {
- a = self->data.normal.actions->data;
- action_run(self->data.normal.actions, a->data.any.c, state, time);
+ if (self->id == -1) {
+ if (self->data.normal.data) /* it's set to NULL if its destroyed */
+ client_activate(self->data.normal.data, FALSE, TRUE);
}
+ else
+ screen_set_desktop(self->id, TRUE);
}
static void desk_menu_destroy(ObMenu *menu, gpointer data)
GList *eit;
for (eit = mit->entries; eit; eit = g_list_next(eit)) {
ObMenuEntry *meit = eit->data;
- if (meit->type == OB_MENU_ENTRY_TYPE_NORMAL) {
- ObAction *a = meit->data.normal.actions->data;
- ObClient *c = a->data.any.c;
- if (c == client)
- a->data.any.c = NULL;
+ if (meit->type == OB_MENU_ENTRY_TYPE_NORMAL &&
+ meit->data.normal.data == client)
+ {
+ meit->data.normal.data = NULL;
}
}
}
#include "window.h"
#include "openbox.h"
#include "dock.h"
+#include "actions.h"
#include "client.h"
#include "xerror.h"
#include "prop.h"
#include <glib.h>
-typedef struct {
- gboolean active;
- guint state;
- ObClient *client;
- ObActionsAct *action;
-} ObInteractiveState;
-
KeyBindingTree *keyboard_firstnode = NULL;
static ObPopup *popup = NULL;
-static ObInteractiveState istate;
static KeyBindingTree *curpos;
static void grab_keys(gboolean grab)
return TRUE;
}
-static void keyboard_interactive_end(guint state, gboolean cancel, Time time,
- gboolean ungrab)
-{
#if 0
- GSList *alist;
-
- g_assert(istate.active);
-
- /* ungrab first so they won't be NotifyWhileGrabbed */
- if (ungrab)
- ungrab_keyboard();
-
- /* set this before running the actions so they know the keyboard is not
- grabbed */
- istate.active = FALSE;
-
- alist = g_slist_append(NULL, istate.action);
- action_run_interactive(alist, istate.client, state, time, cancel, TRUE);
- g_slist_free(alist);
-
- keyboard_reset_chains(0);
-#endif
-}
-
-static void keyboard_interactive_end_client(ObClient *client, gpointer data)
-{
- if (istate.active && istate.client == client)
- istate.client = NULL;
-}
-
-
-void keyboard_interactive_cancel()
-{
- keyboard_interactive_end(0, TRUE, event_curtime, TRUE);
-}
-
-gboolean keyboard_interactive_grab(guint state, ObClient *client,
- ObActionsAct *action)
-{
-#if 0
- g_assert(action->data.any.interactive);
-
- if (!istate.active) {
- if (!grab_keyboard())
- return FALSE;
- } else if (action->func != istate.action->func) {
- keyboard_interactive_end(state, TRUE, action->data.any.time, FALSE);
- }
-
- istate.active = TRUE;
- istate.state = state;
- istate.client = client;
- istate.action = action;
-
-#endif
- return TRUE;
-}
-
gboolean keyboard_process_interactive_grab(const XEvent *e, ObClient **client)
{
gboolean handled = FALSE;
return handled;
}
+#endif
void keyboard_event(ObClient *client, const XEvent *e)
{
set_curpos(p);
else {
GSList *it;
- gboolean inter = FALSE;
- for (it = p->actions; it && !inter; it = g_slist_next(it))
- if (((ObActionsAct*)it->data)->data.any.interactive)
- inter = TRUE;
- if (!inter) /* don't reset if the action is interactive */
+ for (it = p->actions; it; it = g_slist_next(it))
+ if (actions_act_is_interactive(it->data)) break;
+ if (it == NULL) /* reset if the actions are not interactive */
keyboard_reset_chains(0);
- action_run_key(p->actions, client, e->xkey.state,
- e->xkey.x_root, e->xkey.y_root,
- e->xkey.time);
+ actions_run_acts(p->actions, OB_USER_ACTION_KEYBOARD_KEY,
+ e->xkey.time, e->xkey.state,
+ e->xkey.x_root, e->xkey.y_root,
+ OB_FRAME_CONTEXT_NONE, client);
}
break;
}
}
}
-gboolean keyboard_interactively_grabbed()
-{
- return istate.active;
-}
-
void keyboard_startup(gboolean reconfig)
{
grab_keys(TRUE);
popup = popup_new(FALSE);
popup_set_text_align(popup, RR_JUSTIFY_CENTER);
-
- if (!reconfig)
- client_add_destroy_notify(keyboard_interactive_end_client, NULL);
}
void keyboard_shutdown(gboolean reconfig)
{
- if (!reconfig)
- client_remove_destroy_notify(keyboard_interactive_end_client);
-
- if (istate.active)
- keyboard_interactive_cancel();
-
ob_main_loop_timeout_remove(ob_main_loop, chain_timeout);
keyboard_unbind_all();
*/
void keyboard_reset_chains(gint break_chroots);
-gboolean keyboard_interactive_grab(guint state, struct _ObClient *client,
- struct _ObActionsAct *action);
-gboolean keyboard_process_interactive_grab(const XEvent *e,
- struct _ObClient **client);
-gboolean keyboard_interactively_grabbed();
-
-void keyboard_interactive_cancel();
-
#endif
#include "keyboard.h"
#include "translate.h"
+#include "actions.h"
#include <glib.h>
void tree_destroy(KeyBindingTree *tree)
g_free(it->data);
g_list_free(tree->keylist);
for (sit = tree->actions; sit != NULL; sit = sit->next)
- action_unref(sit->data);
+ actions_act_unref(sit->data);
g_slist_free(tree->actions);
}
g_free(tree);
*/
#include "mainloop.h"
-#include "action.h"
-#include "client.h"
#include "event.h"
#include <stdio.h>
gboolean signal_fired;
guint signals_fired[NUM_SIGNALS];
GSList *signal_handlers[NUM_SIGNALS];
-
- GSList *action_queue;
};
struct _ObMainLoopTimer
all_loops = g_slist_prepend(all_loops, loop);
- loop->action_queue = NULL;
-
return loop;
}
}
}
- for (it = loop->action_queue; it; it = g_slist_next(it))
- action_unref(it->data);
- g_slist_free(loop->action_queue);
-
g_free(loop);
}
}
h->func(h->fd, h->data);
}
-void ob_main_loop_queue_action(ObMainLoop *loop, ObAction *act)
-{
- loop->action_queue = g_slist_append(loop->action_queue, action_copy(act));
-}
-
-static void ob_main_loop_client_destroy(ObClient *client, gpointer data)
-{
- ObMainLoop *loop = data;
- GSList *it;
-
- for (it = loop->action_queue; it; it = g_slist_next(it)) {
- ObAction *act = it->data;
-
- if (act->data.any.c == client)
- act->data.any.c = NULL;
- }
-}
-
void ob_main_loop_run(ObMainLoop *loop)
{
XEvent e;
struct timeval *wait;
fd_set selset;
GSList *it;
- ObAction *act;
loop->run = TRUE;
loop->running = TRUE;
- client_add_destroy_notify(ob_main_loop_client_destroy, loop);
-
while (loop->run) {
if (loop->signal_fired) {
guint i;
h->func(&e, h->data);
}
} while (XPending(loop->display) && loop->run);
- } else if (loop->action_queue) {
- /* only fire off one action at a time, then go back for more
- X events, since the action might cause some X events (like
- FocusIn :) */
-
- do {
- act = loop->action_queue->data;
- if (act->data.any.client_action == OB_CLIENT_ACTION_ALWAYS &&
- !act->data.any.c)
- {
- loop->action_queue =
- g_slist_delete_link(loop->action_queue,
- loop->action_queue);
- action_unref(act);
- act = NULL;
- }
- } while (!act && loop->action_queue && loop->run);
-
- if (act) {
- event_curtime = act->data.any.time;
- act->func(&act->data);
- event_curtime = CurrentTime;
- loop->action_queue =
- g_slist_delete_link(loop->action_queue,
- loop->action_queue);
- action_unref(act);
- }
} else {
/* this only runs if there were no x events received */
}
}
- client_remove_destroy_notify(ob_main_loop_client_destroy);
-
loop->running = FALSE;
}
gpointer data,
gboolean cancel_dest);
-struct _ObAction;
-
-/*! Queues an action, which will be run when there are no more X events
- to process */
-void ob_main_loop_queue_action(ObMainLoop *loop, struct _ObAction *act);
-
void ob_main_loop_run(ObMainLoop *loop);
void ob_main_loop_exit(ObMainLoop *loop);
#include "openbox.h"
#include "mainloop.h"
#include "stacking.h"
+#include "grab.h"
#include "client.h"
#include "config.h"
+#include "actions.h"
#include "screen.h"
#include "menuframe.h"
#include "keyboard.h"
for (node = node->children; node; node = node->next)
if (!xmlStrcasecmp(node->name, (const xmlChar*) "action")) {
- ObAction *a = action_parse
- (i, doc, node, OB_USER_ACTION_MENU_SELECTION);
+ ObActionsAct *a = actions_parse(i, doc, node);
if (a)
acts = g_slist_append(acts, a);
}
ObMenu *self;
ObMenuFrame *frame;
- if (!(self = menu_from_name(name))
- || keyboard_interactively_grabbed()) return;
+ if (!(self = menu_from_name(name)) ||
+ grab_on_keyboard() || grab_on_pointer()) return;
/* if the requested menu is already the top visible menu, then don't
bother */
frame = menu_frame_new(self, 0, client);
if (!menu_frame_show_topmenu(frame, x, y, button))
menu_frame_free(frame);
- else if (!button) {
- /* select the first entry if it's not a submenu and we opened
- * the menu with the keyboard, and skip all headers */
- GList *it = frame->entries;
- while (it) {
- ObMenuEntryFrame *e = it->data;
- if (e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) {
- menu_frame_select(frame, e, FALSE);
- break;
- } else if (e->entry->type == OB_MENU_ENTRY_TYPE_SEPARATOR)
- it = g_list_next(it);
- else
- break;
+ else {
+ if (!button) {
+ /* select the first entry if it's not a submenu and we opened
+ * the menu with the keyboard, and skip all headers */
+ GList *it = frame->entries;
+ while (it) {
+ ObMenuEntryFrame *e = it->data;
+ if (e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) {
+ menu_frame_select(frame, e, FALSE);
+ break;
+ } else if (e->entry->type == OB_MENU_ENTRY_TYPE_SEPARATOR)
+ it = g_list_next(it);
+ else
+ break;
+ }
}
- }
- if (!button)
- menu_can_hide = TRUE;
- else {
- menu_can_hide = FALSE;
- ob_main_loop_timeout_add(ob_main_loop,
- config_menu_hide_delay * 1000,
- menu_hide_delay_func,
- NULL, g_direct_equal, NULL);
+ /* reset the hide timer */
+ if (!button)
+ menu_can_hide = TRUE;
+ else {
+ menu_can_hide = FALSE;
+ ob_main_loop_timeout_add(ob_main_loop,
+ config_menu_hide_delay * 1000,
+ menu_hide_delay_func,
+ NULL, g_direct_equal, NULL);
+ }
}
}
case OB_MENU_ENTRY_TYPE_NORMAL:
g_free(self->data.normal.label);
while (self->data.normal.actions) {
- action_unref(self->data.normal.actions->data);
+ actions_act_unref(self->data.normal.actions->data);
self->data.normal.actions =
g_slist_delete_link(self->data.normal.actions,
self->data.normal.actions);
RrColor *mask_selected_color;
RrColor *mask_disabled_color;
RrColor *mask_disabled_selected_color;
+
+ gpointer data;
};
struct _ObSubmenuMenuEntry {
#include "client.h"
#include "menu.h"
#include "screen.h"
+#include "actions.h"
#include "grab.h"
#include "openbox.h"
#include "mainloop.h"
if (func)
func(entry, frame, client, state, data, time);
else
- action_run(acts, client, state, time);
+ actions_run_acts(acts, OB_USER_ACTION_MENU_SELECTION,
+ time, state, -1, -1, OB_FRAME_CONTEXT_NONE,
+ client);
}
}