X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient_menu.c;h=c6cdd63557d56a2506fb789ce1e20538d12d8e42;hb=HEAD;hp=011e3ec119bfd40bce1a33f09e030a84c4186985;hpb=e0e1d4ba7e150b215b55029ddbff3c824b94caf7;p=chaz%2Fopenbox diff --git a/openbox/client_menu.c b/openbox/client_menu.c index 011e3ec1..c6cdd635 100644 --- a/openbox/client_menu.c +++ b/openbox/client_menu.c @@ -19,11 +19,16 @@ #include "debug.h" #include "menu.h" #include "menuframe.h" +#include "config.h" #include "screen.h" #include "client.h" +#include "client_menu.h" #include "openbox.h" #include "frame.h" +#include "moveresize.h" +#include "event.h" #include "gettext.h" +#include "obt/prop.h" #include @@ -32,18 +37,17 @@ #define LAYER_MENU_NAME "client-layer-menu" enum { - LAYER_TOP, - LAYER_NORMAL, - LAYER_BOTTOM + LAYER_TOP = 1, + LAYER_NORMAL = 0, + LAYER_BOTTOM = -1 }; enum { CLIENT_SEND_TO, CLIENT_LAYER, CLIENT_ICONIFY, + CLIENT_RESTORE, CLIENT_MAXIMIZE, - CLIENT_RAISE, - CLIENT_LOWER, CLIENT_SHADE, CLIENT_DECORATE, CLIENT_MOVE, @@ -51,121 +55,257 @@ enum { CLIENT_CLOSE }; -static gboolean client_update(ObMenuFrame *frame, gpointer data) +static void set_icon_color(ObMenuEntry *e) +{ + e->data.normal.mask_normal_color = ob_rr_theme->menu_color; + e->data.normal.mask_selected_color = ob_rr_theme->menu_selected_color; + e->data.normal.mask_disabled_color = ob_rr_theme->menu_disabled_color; + e->data.normal.mask_disabled_selected_color = + ob_rr_theme->menu_disabled_selected_color; +} + +static gboolean client_menu_update(ObMenuFrame *frame, gpointer data) { ObMenu *menu = frame->menu; - ObMenuEntry *e; GList *it; if (frame->client == NULL || !client_normal(frame->client)) return FALSE; /* don't show the menu */ for (it = menu->entries; it; it = g_list_next(it)) { - e = it->data; - if (e->type == OB_MENU_ENTRY_TYPE_NORMAL) - e->data.normal.enabled = TRUE; + ObMenuEntry *e = it->data; + gboolean *en = &e->data.normal.enabled; /* save some typing */ + ObClient *c = frame->client; + + if (e->type == OB_MENU_ENTRY_TYPE_NORMAL) { + switch (e->id) { + case CLIENT_ICONIFY: + *en = c->functions & OB_CLIENT_FUNC_ICONIFY; + break; + case CLIENT_RESTORE: + *en = c->max_horz || c->max_vert; + break; + case CLIENT_MAXIMIZE: + *en = ((c->functions & OB_CLIENT_FUNC_MAXIMIZE) && + (!c->max_horz || !c->max_vert)); + break; + case CLIENT_SHADE: + *en = c->functions & OB_CLIENT_FUNC_SHADE; + break; + case CLIENT_MOVE: + *en = c->functions & OB_CLIENT_FUNC_MOVE; + break; + case CLIENT_RESIZE: + *en = c->functions & OB_CLIENT_FUNC_RESIZE; + break; + case CLIENT_CLOSE: + *en = c->functions & OB_CLIENT_FUNC_CLOSE; + break; + case CLIENT_DECORATE: + *en = c->functions & OB_CLIENT_FUNC_UNDECORATE; + break; + default: + *en = TRUE; + } + } } + return TRUE; /* show the menu */ +} - e = menu_find_entry_id(menu, CLIENT_ICONIFY); - e->data.normal.enabled = frame->client->functions & OB_CLIENT_FUNC_ICONIFY; - - e = menu_find_entry_id(menu, CLIENT_MAXIMIZE); - menu_entry_set_label(e, - (frame->client->max_vert || frame->client->max_horz ? - _("Restor&e") : _("Maximiz&e")), TRUE); - e->data.normal.enabled =frame->client->functions & OB_CLIENT_FUNC_MAXIMIZE; - - e = menu_find_entry_id(menu, CLIENT_SHADE); - menu_entry_set_label(e, (frame->client->shaded ? - _("&Roll down") : _("&Roll up")), TRUE); - e->data.normal.enabled = frame->client->functions & OB_CLIENT_FUNC_SHADE; - - e = menu_find_entry_id(menu, CLIENT_MOVE); - e->data.normal.enabled = frame->client->functions & OB_CLIENT_FUNC_MOVE; - - e = menu_find_entry_id(menu, CLIENT_RESIZE); - e->data.normal.enabled = frame->client->functions & OB_CLIENT_FUNC_RESIZE; +static void client_menu_execute(ObMenuEntry *e, ObMenuFrame *f, + ObClient *c, guint state, gpointer data) +{ + gint x, y; + gulong ignore_start; + + if (!c) + return; + + if (!config_focus_under_mouse) + ignore_start = event_start_ignore_all_enters(); + + switch (e->id) { + case CLIENT_ICONIFY: + /* the client won't be on screen anymore so hide the menu */ + menu_frame_hide_all(); + f = NULL; /* and don't update */ + + client_iconify(c, TRUE, FALSE, FALSE); + break; + case CLIENT_RESTORE: + client_maximize(c, FALSE, 0); + break; + case CLIENT_MAXIMIZE: + client_maximize(c, TRUE, 0); + break; + case CLIENT_SHADE: + client_shade(c, !c->shaded); + break; + case CLIENT_DECORATE: + client_set_undecorated(c, !c->undecorated); + break; + case CLIENT_MOVE: + /* this needs to grab the keyboard so hide the menu */ + menu_frame_hide_all(); + f = NULL; /* and don't update */ + + screen_pointer_pos(&x, &y); + moveresize_start(c, x, y, 0, + OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE_KEYBOARD)); + break; + case CLIENT_RESIZE: + /* this needs to grab the keyboard so hide the menu */ + menu_frame_hide_all(); + f = NULL; /* and don't update */ + + screen_pointer_pos(&x, &y); + moveresize_start(c, x, y, 0, + OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_KEYBOARD)); + break; + case CLIENT_CLOSE: + client_close(c); + break; + default: + g_assert_not_reached(); + } - e = menu_find_entry_id(menu, CLIENT_CLOSE); - e->data.normal.enabled = frame->client->functions & OB_CLIENT_FUNC_CLOSE; + if (!config_focus_under_mouse) + event_end_ignore_all_enters(ignore_start); - e = menu_find_entry_id(menu, CLIENT_DECORATE); - e->data.normal.enabled = client_normal(frame->client); - return TRUE; /* show the menu */ + /* update the menu cuz stuff can have changed */ + if (f) { + client_menu_update(f, NULL); + menu_frame_render(f); + } } -static gboolean layer_update(ObMenuFrame *frame, gpointer data) +static gboolean layer_menu_update(ObMenuFrame *frame, gpointer data) { ObMenu *menu = frame->menu; - ObMenuEntry *e; GList *it; if (frame->client == NULL || !client_normal(frame->client)) return FALSE; /* don't show the menu */ for (it = menu->entries; it; it = g_list_next(it)) { - e = it->data; - if (e->type == OB_MENU_ENTRY_TYPE_NORMAL) - e->data.normal.enabled = TRUE; + ObMenuEntry *e = it->data; + gboolean *en = &e->data.normal.enabled; /* save some typing */ + ObClient *c = frame->client; + + if (e->type == OB_MENU_ENTRY_TYPE_NORMAL) { + switch (e->id) { + case LAYER_TOP: + *en = !c->above && (c->functions & OB_CLIENT_FUNC_ABOVE); + break; + case LAYER_NORMAL: + *en = c->above || c->below; + break; + case LAYER_BOTTOM: + *en = !c->below && (c->functions & OB_CLIENT_FUNC_BELOW); + break; + default: + *en = TRUE; + } + } } + return TRUE; /* show the menu */ +} - e = menu_find_entry_id(menu, LAYER_TOP); - e->data.normal.enabled = !frame->client->above; +static void layer_menu_execute(ObMenuEntry *e, ObMenuFrame *f, + ObClient *c, guint state, gpointer data) +{ + gulong ignore_start; - e = menu_find_entry_id(menu, LAYER_NORMAL); - e->data.normal.enabled = (frame->client->above || frame->client->below); + g_assert(c); - e = menu_find_entry_id(menu, LAYER_BOTTOM); - e->data.normal.enabled = !frame->client->below; - return TRUE; /* show the menu */ + if (!config_focus_under_mouse) + ignore_start = event_start_ignore_all_enters(); + + client_set_layer(c, e->id); + + if (!config_focus_under_mouse) + event_end_ignore_all_enters(ignore_start); + + /* update the menu cuz stuff can have changed */ + if (f) { + layer_menu_update(f, NULL); + menu_frame_render(f); + } } -static gboolean send_to_update(ObMenuFrame *frame, gpointer data) +static gboolean send_to_menu_update(ObMenuFrame *frame, gpointer data) { ObMenu *menu = frame->menu; + ObClient *c = frame->client; guint i; - GSList *acts; - ObAction *act; - ObMenuEntry *e;; - - menu_clear_entries(menu); + ObMenuEntry *e; + GList *it; - if (frame->client == NULL || !client_normal(frame->client)) + if (c == NULL || !client_normal(c)) return FALSE; /* don't show the menu */ - for (i = 0; i <= screen_num_desktops; ++i) { - const gchar *name; - guint desk; + if (!data) + menu_clear_entries(menu); - if (i >= screen_num_desktops) { - menu_add_separator(menu, -1, NULL); + if (!menu->entries) { + for (i = 0; i <= screen_num_desktops; ++i) { + const gchar *name; + guint desk; - desk = DESKTOP_ALL; - name = _("All desktops"); - } else { - desk = i; - name = screen_desktop_names[i]; - } + if (i == screen_num_desktops) { + menu_add_separator(menu, -1, NULL); - act = action_from_string("SendToDesktop", - OB_USER_ACTION_MENU_SELECTION); - act->data.sendto.desk = desk; - act->data.sendto.follow = FALSE; - acts = g_slist_prepend(NULL, act); - e = menu_add_normal(menu, desk, name, acts, FALSE); + desk = DESKTOP_ALL; + name = _("All desktops"); + } else { + desk = i; + name = screen_desktop_names[i]; + } + + e = menu_add_normal(menu, desk, name, NULL, FALSE); + e->id = desk; + } + } - if (frame->client->desktop == desk) - e->data.normal.enabled = FALSE; + for (it = menu->entries; it; it = g_list_next(it)) { + ObMenuEntry *e = it->data; + guint desk = e->id; + + e->data.normal.enabled = c->desktop != desk; + + if ((desk == DESKTOP_ALL && c->desktop != DESKTOP_ALL) || + (c->desktop == DESKTOP_ALL && desk == screen_desktop)) + { + e->data.normal.mask = ob_rr_theme->btn_desk->mask; + set_icon_color(e); + } else + e->data.normal.mask = NULL; } + return TRUE; /* show the menu */ } +static void send_to_menu_execute(ObMenuEntry *e, ObMenuFrame *f, + ObClient *c, guint state, gpointer data) +{ + g_assert(c); + + client_set_desktop(c, e->id, FALSE, FALSE); + if (f && c->desktop != screen_desktop && c->desktop != DESKTOP_ALL) + /* the client won't even be on the screen anymore, so hide the menu */ + menu_frame_hide_all(); + else if (f) { + send_to_menu_update(f, (gpointer)1); + menu_frame_render(f); + } +} + static void client_menu_place(ObMenuFrame *frame, gint *x, gint *y, - gint button, gpointer data) + gboolean mouse, gpointer data) { gint dx, dy; - if (button == 0 && frame->client) { + if (!mouse && frame->client) { *x = frame->client->frame->area.x; /* try below the titlebar */ @@ -223,99 +363,59 @@ static void client_menu_place(ObMenuFrame *frame, gint *x, gint *y, } } -void client_menu_startup() +void client_menu_startup(void) { - GSList *acts; ObMenu *menu; ObMenuEntry *e; - menu = menu_new(LAYER_MENU_NAME, _("&Layer"), TRUE, NULL); + menu = menu_new(LAYER_MENU_NAME, _("_Layer"), TRUE, NULL); menu_show_all_shortcuts(menu, TRUE); - menu_set_update_func(menu, layer_update); - - acts = g_slist_prepend(NULL, action_from_string - ("SendToTopLayer", OB_USER_ACTION_MENU_SELECTION)); - menu_add_normal(menu, LAYER_TOP, _("Always on &top"), acts, TRUE); - - acts = g_slist_prepend(NULL, action_from_string - ("SendToNormalLayer", - OB_USER_ACTION_MENU_SELECTION)); - menu_add_normal(menu, LAYER_NORMAL, _("&Normal"), acts, TRUE); - - acts = g_slist_prepend(NULL, action_from_string - ("SendToBottomLayer", - OB_USER_ACTION_MENU_SELECTION)); - menu_add_normal(menu, LAYER_BOTTOM, _("Always on &bottom"),acts, TRUE); - + menu_set_update_func(menu, layer_menu_update); + menu_set_execute_func(menu, layer_menu_execute); - menu = menu_new(SEND_TO_MENU_NAME, _("&Send to desktop"), TRUE, NULL); - menu_set_update_func(menu, send_to_update); + menu_add_normal(menu, LAYER_TOP, _("Always on _top"), NULL, TRUE); + menu_add_normal(menu, LAYER_NORMAL, _("_Normal"), NULL, TRUE); + menu_add_normal(menu, LAYER_BOTTOM, _("Always on _bottom"),NULL, TRUE); + menu = menu_new(SEND_TO_MENU_NAME, _("_Send to desktop"), TRUE, NULL); + menu_set_update_func(menu, send_to_menu_update); + menu_set_execute_func(menu, send_to_menu_execute); menu = menu_new(CLIENT_MENU_NAME, _("Client menu"), TRUE, NULL); menu_show_all_shortcuts(menu, TRUE); - menu_set_update_func(menu, client_update); + menu_set_update_func(menu, client_menu_update); menu_set_place_func(menu, client_menu_place); + menu_set_execute_func(menu, client_menu_execute); menu_add_submenu(menu, CLIENT_SEND_TO, SEND_TO_MENU_NAME); menu_add_submenu(menu, CLIENT_LAYER, LAYER_MENU_NAME); - acts = g_slist_prepend(NULL, action_from_string - ("Iconify", OB_USER_ACTION_MENU_SELECTION)); - e = menu_add_normal(menu, CLIENT_ICONIFY, _("Ico&nify"), acts, TRUE); - e->data.normal.mask = ob_rr_theme->iconify_mask; - e->data.normal.mask_normal_color = ob_rr_theme->menu_color; - e->data.normal.mask_disabled_color = ob_rr_theme->menu_disabled_color; - e->data.normal.mask_selected_color = ob_rr_theme->menu_selected_color; + e = menu_add_normal(menu, CLIENT_RESTORE, _("R_estore"), NULL, TRUE); + e->data.normal.mask = ob_rr_theme->btn_max->toggled_mask; + set_icon_color(e); - acts = g_slist_prepend(NULL, action_from_string - ("ToggleMaximizeFull", - OB_USER_ACTION_MENU_SELECTION)); - e = menu_add_normal(menu, CLIENT_MAXIMIZE, _("Maximiz&e"), acts, TRUE); - e->data.normal.mask = ob_rr_theme->max_mask; - e->data.normal.mask_normal_color = ob_rr_theme->menu_color; - e->data.normal.mask_disabled_color = ob_rr_theme->menu_disabled_color; - e->data.normal.mask_selected_color = ob_rr_theme->menu_selected_color; + menu_add_normal(menu, CLIENT_MOVE, _("_Move"), NULL, TRUE); - acts = g_slist_prepend(NULL, action_from_string - ("Raise", OB_USER_ACTION_MENU_SELECTION)); - menu_add_normal(menu, CLIENT_RAISE, _("Raise to &top"), acts, TRUE); + menu_add_normal(menu, CLIENT_RESIZE, _("Resi_ze"), NULL, TRUE); - acts = g_slist_prepend(NULL, action_from_string - ("Lower", OB_USER_ACTION_MENU_SELECTION)); - menu_add_normal(menu, CLIENT_LOWER, _("Lower to &bottom"),acts, TRUE); + e = menu_add_normal(menu, CLIENT_ICONIFY, _("Ico_nify"), NULL, TRUE); + e->data.normal.mask = ob_rr_theme->btn_iconify->mask; + set_icon_color(e); - acts = g_slist_prepend(NULL, action_from_string - ("ToggleShade", OB_USER_ACTION_MENU_SELECTION)); - e = menu_add_normal(menu, CLIENT_SHADE, _("&Roll up"), acts, TRUE); - e->data.normal.mask = ob_rr_theme->shade_mask; - e->data.normal.mask_normal_color = ob_rr_theme->menu_color; - e->data.normal.mask_disabled_color = ob_rr_theme->menu_disabled_color; - e->data.normal.mask_selected_color = ob_rr_theme->menu_selected_color; - - acts = g_slist_prepend(NULL, action_from_string - ("ToggleDecorations", - OB_USER_ACTION_MENU_SELECTION)); - menu_add_normal(menu, CLIENT_DECORATE, _("&Decorate"), acts, TRUE); - - menu_add_separator(menu, -1, NULL); + e = menu_add_normal(menu, CLIENT_MAXIMIZE, _("Ma_ximize"), NULL, TRUE); + e->data.normal.mask = ob_rr_theme->btn_max->mask; + set_icon_color(e); - acts = g_slist_prepend(NULL, action_from_string - ("Move", OB_USER_ACTION_MENU_SELECTION)); - menu_add_normal(menu, CLIENT_MOVE, _("&Move"), acts, TRUE); + e = menu_add_normal(menu, CLIENT_SHADE, _("_Roll up/down"), NULL, TRUE); + e->data.normal.mask = ob_rr_theme->btn_shade->mask; + set_icon_color(e); - acts = g_slist_prepend(NULL, action_from_string - ("Resize", OB_USER_ACTION_MENU_SELECTION)); - menu_add_normal(menu, CLIENT_RESIZE, _("Resi&ze"), acts, TRUE); + menu_add_normal(menu, CLIENT_DECORATE, _("Un/_Decorate"), NULL, TRUE); menu_add_separator(menu, -1, NULL); - acts = g_slist_prepend(NULL, action_from_string - ("Close", OB_USER_ACTION_MENU_SELECTION)); - e = menu_add_normal(menu, CLIENT_CLOSE, _("&Close"), acts, TRUE); - e->data.normal.mask = ob_rr_theme->close_mask; - e->data.normal.mask_normal_color = ob_rr_theme->menu_color; - e->data.normal.mask_disabled_color = ob_rr_theme->menu_disabled_color; - e->data.normal.mask_selected_color = ob_rr_theme->menu_selected_color; + e = menu_add_normal(menu, CLIENT_CLOSE, _("_Close"), NULL, TRUE); + e->data.normal.mask = ob_rr_theme->btn_close->mask; + set_icon_color(e); }