all repos — openbox @ 615cbd96075905d75533f9b615c4ee6a75f4f9a4

openbox fork - make it a bit more like ryudo

change the menu plugin interface, no need for the create/destroy functions any more.
redo the client-menu plugin to work with the new menu api
Dana Jansens danakj@orodu.net
commit

615cbd96075905d75533f9b615c4ee6a75f4f9a4

parent

9290376bbbb8b29411f59a35e5477f25304fe205

M Makefile.amMakefile.am

@@ -26,10 +26,10 @@ kernel/openbox \

tools/kdetrayproxy/kdetrayproxy plugin_LTLIBRARIES = \ - plugins/placement/placement.la + plugins/placement/placement.la \ + plugins/menu/client_menu.la # plugins/menu/timed_menu.la \ # plugins/menu/fifo_menu.la \ -# plugins/menu/client_menu.la \ # plugins/menu/include_menu.la \ # plugins/menu/client_list_menu.la
M data/menudata/menu

@@ -28,8 +28,8 @@ </item>

</menu> <menu id="root-menu" label="Openbox 3"> - <menu id="apps-menu"> - <menu id="games-menu"> + <menu id="apps-menu" /> + <menu id="games-menu" /> <separator /> <item label="Restart"> <action name="restart" />
M openbox/client.copenbox/client.c

@@ -17,7 +17,7 @@ #include "dispatch.h"

#include "openbox.h" #include "group.h" #include "config.h" -#include "menu.h" +#include "menuframe.h" #include "keyboard.h" #include "mouse.h" #include "render/render.h"

@@ -406,7 +406,9 @@

if (moveresize_client == self) moveresize_end(TRUE); - /* XXX close any windows that are attached to this window */ + /* menus can be associated with a client, so close any that are since + we are disappearing now */ + menu_frame_hide_all_client(self); if (focus_client == self) { XEvent e;
M openbox/event.copenbox/event.c

@@ -1183,8 +1183,8 @@ case MotionNotify:

if ((f = menu_frame_under(ev->xmotion.x_root, ev->xmotion.y_root))) { menu_frame_move_on_screen(f); - if (e = menu_entry_frame_under(ev->xmotion.x_root, - ev->xmotion.y_root)) + if ((e = menu_entry_frame_under(ev->xmotion.x_root, + ev->xmotion.y_root))) menu_frame_select(f, e); } break;
M openbox/menu.copenbox/menu.c

@@ -44,11 +44,11 @@

if (state->menus) { if (parse_attr_string("label", node, &label)) { GSList *acts = NULL; - + for (node = node->xmlChildrenNode; node; node = node->next) if (!xmlStrcasecmp(node->name, (const xmlChar*) "action")) acts = g_slist_append(acts, action_parse(doc, node)); - menu_add_normal(state->menus->data, label, acts); + menu_add_normal(state->menus->data, 0, label, acts); g_free(label); } }

@@ -59,9 +59,9 @@ xmlDocPtr doc, xmlNodePtr node,

gpointer data) { ObMenuParseState *state = data; - + if (state->menus) - menu_add_separator(state->menus->data); + menu_add_separator(state->menus->data, 0); } static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,

@@ -85,7 +85,7 @@ }

} if (state->menus) - menu_add_submenu(state->menus->data, name); + menu_add_submenu(state->menus->data, 0, name); parse_menu_fail: g_free(name);

@@ -95,6 +95,7 @@

void menu_destroy_hash_value(ObMenu *self) { + /* XXX make sure its not visible */ menu_clear_entries_internal(self); g_free(self->name); g_free(self->title);

@@ -110,6 +111,7 @@ void menu_shutdown()

{ menu_frame_hide_all(); g_hash_table_destroy(menu_hash); + menu_hash = NULL; } void menu_parse()

@@ -170,6 +172,14 @@

return TRUE; } +void menu_free(gchar *name) +{ + ObMenu *self; + + if (!(self = menu_from_name(name))) return; + g_hash_table_remove(menu_hash, self->name); +} + void menu_show(gchar *name, gint x, gint y, ObClient *client) { ObMenu *self;

@@ -177,14 +187,12 @@ ObMenuFrame *frame;

if (!(self = menu_from_name(name))) return; - /* XXX update entries */ - frame = menu_frame_new(self, client); menu_frame_move(frame, x, y); menu_frame_show(frame, NULL); } -static ObMenuEntry* menu_entry_new(ObMenu *menu, ObMenuEntryType type) +static ObMenuEntry* menu_entry_new(ObMenu *menu, ObMenuEntryType type, gint id) { ObMenuEntry *self;

@@ -193,6 +201,7 @@

self = g_new0(ObMenuEntry, 1); self->type = type; self->menu = menu; + self->id = id; self->enabled = TRUE; return self; }

@@ -238,21 +247,21 @@ self->entries = g_list_delete_link(self->entries, self->entries);

} } -void menu_add_normal(gchar *name, gchar *label, GSList *actions) +void menu_add_normal(gchar *name, gint id, gchar *label, GSList *actions) { ObMenu *self; ObMenuEntry *e; if (!(self = menu_from_name(name))) return; - e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_NORMAL); + e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_NORMAL, id); e->data.normal.label = g_strdup(label); e->data.normal.actions = actions; self->entries = g_list_append(self->entries, e); } -void menu_add_submenu(gchar *name, gchar *submenu) +void menu_add_submenu(gchar *name, gint id, gchar *submenu) { ObMenu *self, *sub; ObMenuEntry *e;

@@ -260,20 +269,44 @@

if (!(self = menu_from_name(name))) return; if (!(sub = menu_from_name(submenu))) return; - e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_SUBMENU); + e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_SUBMENU, id); e->data.submenu.submenu = sub; self->entries = g_list_append(self->entries, e); } -void menu_add_separator(gchar *name) +void menu_add_separator(gchar *name, gint id) { ObMenu *self; ObMenuEntry *e; if (!(self = menu_from_name(name))) return; - e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_SEPARATOR); + e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_SEPARATOR, id); self->entries = g_list_append(self->entries, e); } + +void menu_set_update_func(gchar *name, ObMenuUpdateFunc func) +{ + ObMenu *self; + + if (!(self = menu_from_name(name))) return; + self->update_func = func; +} + +ObMenuEntry* menu_find_entry_id(ObMenu *self, gint id) +{ + ObMenuEntry *ret = NULL; + GList *it; + + for (it = self->entries; it; it = g_list_next(it)) { + ObMenuEntry *e = it->data; + + if (e->id == id) { + ret = e; + break; + } + } + return ret; +}
M openbox/menu.hopenbox/menu.h

@@ -17,9 +17,9 @@ typedef struct _ObNormalMenuEntry ObNormalMenuEntry;

typedef struct _ObSubmenuMenuEntry ObSubmenuMenuEntry; typedef struct _ObSeparatorMenuEntry ObSeparatorMenuEntry; -extern GList *menu_visible; - +typedef void (*ObMenuUpdateFunc)(struct _ObMenuFrame *frame, gpointer data); +extern GList *menu_visible; struct _ObMenu {

@@ -33,6 +33,8 @@ GList *entries;

/* plugin data */ gpointer data; + + ObMenuUpdateFunc update_func; }; typedef enum

@@ -62,6 +64,8 @@ {

ObMenuEntryType type; ObMenu *menu; + gint id; + /* state */ gboolean enabled;

@@ -78,13 +82,18 @@

void menu_parse(); gboolean menu_new(gchar *name, gchar *title, gpointer data); +void menu_free(gchar *name); + +void menu_set_update_func(gchar *name, ObMenuUpdateFunc func); void menu_show(gchar *name, gint x, gint y, struct _ObClient *client); /* functions for building menus */ void menu_clear_entries(gchar *name); -void menu_add_normal(gchar *name, gchar *label, GSList *actions); -void menu_add_submenu(gchar *name, gchar *submenu); -void menu_add_separator(gchar *name); +void menu_add_normal(gchar *name, gint id, gchar *label, GSList *actions); +void menu_add_submenu(gchar *name, gint id, gchar *submenu); +void menu_add_separator(gchar *name, gint id); + +ObMenuEntry* menu_find_entry_id(ObMenu *self, gint id); #endif
M openbox/menuframe.copenbox/menuframe.c

@@ -37,6 +37,7 @@ self = g_new0(ObMenuFrame, 1);

self->type = Window_Menu; self->menu = menu; self->selected = NULL; + self->show_title = TRUE; self->client = client; attr.event_mask = FRAME_EVENTMASK;

@@ -51,12 +52,16 @@

self->a_title = RrAppearanceCopy(ob_rr_theme->a_menu_title); self->a_items = RrAppearanceCopy(ob_rr_theme->a_menu); + stacking_add(MENU_AS_WINDOW(self)); + return self; } void menu_frame_free(ObMenuFrame *self) { if (self) { + stacking_remove(MENU_AS_WINDOW(self)); + XDestroyWindow(ob_display, self->items); XDestroyWindow(ob_display, self->title); XDestroyWindow(ob_display, self->window);

@@ -263,7 +268,7 @@ XSetWindowBorderWidth(ob_display, self->window, ob_rr_theme->bwidth);

XSetWindowBorder(ob_display, self->window, RrColorPixel(ob_rr_theme->b_color)); - if (!self->parent && self->menu->title) { + if (!self->parent && self->show_title) { XMoveWindow(ob_display, self->title, -ob_rr_theme->bwidth, h - ob_rr_theme->bwidth);

@@ -344,7 +349,7 @@ XResizeWindow(ob_display, self->items, w, allitems_h);

self->inner_w = w; - if (!self->parent && self->title) { + if (!self->parent && self->show_title) { XResizeWindow(ob_display, self->title, w, self->title_h - ob_rr_theme->bwidth); RrPaint(self->a_title, self->title,

@@ -411,6 +416,8 @@

if (!g_list_find(menu_frame_visible, self)) { menu_frame_visible = g_list_prepend(menu_frame_visible, self); + if (self->menu->update_func) + self->menu->update_func(self, self->menu->data); menu_frame_update(self); }

@@ -443,10 +450,22 @@ }

void menu_frame_hide_all() { - while (menu_frame_visible) - menu_frame_hide(menu_frame_visible->data); + GList *it = g_list_last(menu_frame_visible); + if (it) + menu_frame_hide(it->data); } +void menu_frame_hide_all_client(ObClient *client) +{ + GList *it = g_list_last(menu_frame_visible); + if (it) { + ObMenuFrame *f = it->data; + if (f->client == client) + menu_frame_hide(f); + } +} + + ObMenuFrame* menu_frame_under(gint x, gint y) { ObMenuFrame *ret = NULL;

@@ -488,6 +507,7 @@

void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry) { ObMenuEntryFrame *old = self->selected; + ObMenuFrame *oldchild = self->child; if (old == entry) return;

@@ -496,11 +516,11 @@ self->selected = entry;

else self->selected = NULL; - if (old) { + if (old) menu_entry_frame_render(old); - if (old->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) - menu_frame_hide(self->child); - } + if (oldchild) + menu_frame_hide(oldchild); + if (self->selected) { menu_entry_frame_render(self->selected);

@@ -519,7 +539,7 @@ menu_frame_move(f,

self->frame->area.x + self->frame->area.width - ob_rr_theme->menu_overlap, self->frame->area.y + self->frame->title_h + - self->area.y); + self->area.y + ob_rr_theme->menu_overlap); menu_frame_show(f, self->frame); }

@@ -528,6 +548,9 @@ {

if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) { GSList *it; + /* release grabs before executing the shit */ + menu_frame_hide_all(); + for (it = self->entry->data.normal.actions; it; it = g_slist_next(it)) {

@@ -535,6 +558,5 @@ ObAction *act = it->data;

act->data.any.c = self->frame->client; act->func(&act->data); } - menu_frame_hide_all(); } }
M openbox/menuframe.hopenbox/menuframe.h

@@ -31,6 +31,12 @@

ObMenuFrame *parent; ObMenuFrame *child; + GList *entries; + ObMenuEntryFrame *selected; + + /* If a titlebar is displayed for the menu or not (for top-level menus) */ + gboolean show_title; + /* On-screen area (including borders!) */ Rect area; gint inner_w; /* inside the borders */

@@ -38,9 +44,6 @@ gint title_h; /* includes the bwidth below it */

gint item_h; /* height of all normal items */ gint text_x; /* offset at which the text appears in the items */ gint text_w; /* width of the text area in the items */ - - GList *entries; - ObMenuEntryFrame *selected; Window title; Window items;

@@ -82,6 +85,7 @@ void menu_frame_show(ObMenuFrame *self, ObMenuFrame *parent);

void menu_frame_hide(ObMenuFrame *self); void menu_frame_hide_all(); +void menu_frame_hide_all_client(struct _ObClient *client); void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry);
M openbox/openbox.copenbox/openbox.c

@@ -266,8 +266,8 @@

dock_remove_all(); client_unmanage_all(); - menu_shutdown(); /* destroy menus before unloading plugins */ plugin_shutdown(); /* calls all the plugins' shutdown functions */ + menu_shutdown(); mouse_shutdown(); keyboard_shutdown(); dock_shutdown();
M openbox/plugin.copenbox/plugin.c

@@ -11,8 +11,6 @@

PluginSetupConfig config; PluginStartup startup; PluginShutdown shutdown; - PluginCreate create; - PluginDestroy destroy; } Plugin; static gpointer load_sym(GModule *module, char *name, char *symbol,

@@ -58,9 +56,6 @@ p->startup = (PluginStartup)load_sym(p->module, name, "plugin_startup",

FALSE); p->shutdown = (PluginShutdown)load_sym(p->module, name, "plugin_shutdown", FALSE); - p->create = (PluginCreate)load_sym(p->module, name, "plugin_create", TRUE); - p->destroy = (PluginDestroy)load_sym(p->module, name, "plugin_destroy", - TRUE); if (p->config == NULL || p->startup == NULL || p->shutdown == NULL) { g_module_close(p->module);

@@ -174,41 +169,3 @@ }

g_io_channel_unref(io); } } - -void *plugin_create(char *name, void *data) -{ - Plugin *p = (Plugin *)g_datalist_get_data(&plugins, name); - - if (p == NULL) { - g_warning("Unable to find plugin for create: %s", name); - return NULL; - } - - if (p->create == NULL || p->destroy == NULL) { - g_critical("Unsupported create/destroy: %s", name); - return NULL; - } - - return p->create(data); -} - -void plugin_destroy(char *name, void *data) -{ - Plugin *p = (Plugin *)g_datalist_get_data(&plugins, name); - - if (p == NULL) { - g_critical("Unable to find plugin for destroy: %s", name); - /* really shouldn't happen, but attempt to free something anyway? */ - g_free(data); - return; - } - - if (p->destroy == NULL || p->create == NULL) { - g_critical("Unsupported create/destroy: %s", name); - /* really, really shouldn't happen, but attempt to free anyway? */ - g_free(data); - return; - } - - p->destroy(data); -}
M openbox/plugin.hopenbox/plugin.h

@@ -15,9 +15,4 @@ /* load a plugin, but don't warn about reopens. for menus */

gboolean plugin_open_reopen(char *name, struct _ObParseInst *i); void plugin_close(char *name); -/* call plugin's generic constructor */ -void *plugin_create(char *name, void *data); -/* free memory allocated by plugin_create() */ -void plugin_destroy(char *name, void *object); - #endif
M plugins/interface.hplugins/interface.h

@@ -12,10 +12,4 @@

/* plugin_shutdown() */ typedef void (*PluginShutdown)(void); -/* plugin_create() - for menu plugins only */ -typedef void *(*PluginCreate)(/* TODO */); - -/* plugin_destroy() - for menu plugins only */ -typedef void (*PluginDestroy)(void *); - #endif
M plugins/menu/client_menu.cplugins/menu/client_menu.c

@@ -1,170 +1,175 @@

#include "kernel/debug.h" #include "kernel/menu.h" +#include "kernel/menuframe.h" #include "kernel/screen.h" #include "kernel/client.h" #include "kernel/openbox.h" #include "kernel/frame.h" - -#include "render/theme.h" +#include "gettext.h" #include <glib.h> -static char *PLUGIN_NAME = "client_menu"; +#define CLIENT_MENU_NAME "client-menu" +#define SEND_TO_MENU_NAME "client-send-to-menu" +#define LAYER_MENU_NAME "client-layer-menu" -static ObMenu *send_to_menu; -static ObMenu *layer_menu; +enum { + LAYER_TOP, + LAYER_NORMAL, + LAYER_BOTTOM +}; -typedef struct { - gint foo; -} Client_Menu_Data; +enum { + CLIENT_SEND_TO, + CLIENT_LAYER, + CLIENT_ICONIFY, + CLIENT_MAXIMIZE, + CLIENT_RAISE, + CLIENT_LOWER, + CLIENT_SHADE, + CLIENT_DECORATE, + CLIENT_MOVE, + CLIENT_RESIZE, + CLIENT_CLOSE +}; -#define CLIENT_MENU(m) ((ObMenu *)m) -#define CLIENT_MENU_DATA(m) ((Client_Menu_Data *)((ObMenu *)m)->plugin_data) +void plugin_setup_config() { } -void client_menu_clean_up(ObMenu *m) { +static void client_update(ObMenuFrame *frame, gpointer data) +{ + ObMenu *menu = frame->menu; + ObMenuEntry *e; + + frame->show_title = FALSE; + + if (!frame->client) { + GList *it; + + for (it = menu->entries; it; it = g_list_next(it)) { + ObMenuEntry *e = it->data; + e->enabled = FALSE; + } + return; + } + + e = menu_find_entry_id(menu, CLIENT_ICONIFY); + e->enabled = frame->client->functions & OB_CLIENT_FUNC_ICONIFY; + + e = menu_find_entry_id(menu, CLIENT_MAXIMIZE); + e->enabled = frame->client->functions & OB_CLIENT_FUNC_MAXIMIZE; + + e = menu_find_entry_id(menu, CLIENT_SHADE); + e->enabled = frame->client->functions & OB_CLIENT_FUNC_SHADE; + + e = menu_find_entry_id(menu, CLIENT_MOVE); + e->enabled = frame->client->functions & OB_CLIENT_FUNC_MOVE; + + e = menu_find_entry_id(menu, CLIENT_RESIZE); + e->enabled = frame->client->functions & OB_CLIENT_FUNC_RESIZE; + + e = menu_find_entry_id(menu, CLIENT_CLOSE); + e->enabled = frame->client->functions & OB_CLIENT_FUNC_CLOSE; } -void client_send_to_update(ObMenu *self) +static void send_to_update(ObMenuFrame *frame, gpointer data) { - guint i = 0; - GList *it = self->entries; - - /* check if we have to update. lame */ - while (it != NULL) { - if (i == screen_desktop) { - if (((ObMenuEntry *)it->data)->enabled) - break; + ObMenu *menu = frame->menu; + guint i; + GSList *acts; + ObAction *act; + + menu_clear_entries(SEND_TO_MENU_NAME); + + if (!frame->client) + return; + + for (i = 0; i <= screen_num_desktops; ++i) { + gchar *name; + guint desk; + + if (i >= screen_num_desktops) { + desk = DESKTOP_ALL; + name = _("All desktops"); } else { - if (!((ObMenuEntry *)it->data)->enabled) - break; + desk = i; + name = screen_desktop_names[i]; } - if (i >= screen_num_desktops) - break; - if (strcmp(screen_desktop_names[i], - ((ObMenuEntry *)it->data)->label) != 0) - break; - ++i; - it = it->next; - } - if (it != NULL || i != screen_num_desktops) { - menu_clear(self); - ob_debug("update\n"); - for (i = 0; i < screen_num_desktops; ++i) { - ObMenuEntry *e; - ObAction *a = action_from_string("sendtodesktop"); - a->data.sendto.desk = i; - a->data.sendto.follow = FALSE; - e = menu_entry_new(screen_desktop_names[i], a); - if (i == screen_desktop) - e->enabled = FALSE; - menu_add_entry(self, e); + act = action_from_string("SendToDesktop"); + act->data.sendto.desk = desk; + act->data.sendto.follow = FALSE; + acts = g_slist_prepend(NULL, act); + menu_add_normal(SEND_TO_MENU_NAME, desk, name, acts); + + if (frame->client->desktop == desk) { + ObMenuEntry *e = menu_find_entry_id(menu, desk); + g_assert(e); + e->enabled = FALSE; } - - menu_render(self); } } -void client_menu_show(ObMenu *self, int x, int y, ObClient *client) +void plugin_startup() { - guint i; - gint newy, newx; - Rect *a = NULL; + GSList *acts; + + menu_new(LAYER_MENU_NAME, _("Layer"), NULL); - g_assert(!self->invalid); - g_assert(client); - - for (i = 0; i < screen_num_monitors; ++i) { - a = screen_physical_area_monitor(i); - if (RECT_CONTAINS(*a, x, y)) - break; - } - g_assert(a != NULL); - self->xin_area = i; + acts = g_slist_prepend(NULL, action_from_string("SendToTopLayer")); + menu_add_normal(LAYER_MENU_NAME, LAYER_TOP, _("Always on top"), acts); - newx = MAX(x, client->area.x); - newy = MAX(y, client->area.y); - POINT_SET(self->location, - MIN(newx, client->area.x + client->area.width - self->size.width), - MIN(newy, client->area.y + client->area.height - - self->size.height)); - - XMoveWindow(ob_display, self->frame, self->location.x, self->location.y); + acts = g_slist_prepend(NULL, action_from_string("SendToNormalLayer")); + menu_add_normal(LAYER_MENU_NAME, LAYER_NORMAL, _("Normal"), acts); - if (!self->shown) { - XMapWindow(ob_display, self->frame); - stacking_raise(MENU_AS_WINDOW(self)); - self->shown = TRUE; - } else if (self->shown && self->open_submenu) { - menu_hide(self->open_submenu); - } -} + acts = g_slist_prepend(NULL, action_from_string("SendToBottomLayer")); + menu_add_normal(LAYER_MENU_NAME, LAYER_BOTTOM, _("Always on bottom"),acts); + + + menu_new(SEND_TO_MENU_NAME, _("Send to desktop"), NULL); + menu_set_update_func(SEND_TO_MENU_NAME, send_to_update); + + menu_new(CLIENT_MENU_NAME, _("Client menu"), NULL); + menu_set_update_func(CLIENT_MENU_NAME, client_update); -void plugin_setup_config() { } + menu_add_submenu(CLIENT_MENU_NAME, CLIENT_SEND_TO, SEND_TO_MENU_NAME); -void plugin_shutdown() { } + menu_add_submenu(CLIENT_MENU_NAME, CLIENT_LAYER, LAYER_MENU_NAME); -void plugin_destroy (ObMenu *m) -{ -} + acts = g_slist_prepend(NULL, action_from_string("Iconify")); + menu_add_normal(CLIENT_MENU_NAME, CLIENT_ICONIFY, _("Iconify"), acts); + + acts = g_slist_prepend(NULL, action_from_string("Maximize")); + menu_add_normal(CLIENT_MENU_NAME, CLIENT_MAXIMIZE, _("Maximize"), acts); + + acts = g_slist_prepend(NULL, action_from_string("Raise")); + menu_add_normal(CLIENT_MENU_NAME, CLIENT_RAISE, _("Raise to top"), acts); + + acts = g_slist_prepend(NULL, action_from_string("Lower")); + menu_add_normal(CLIENT_MENU_NAME, CLIENT_LOWER, _("Lower to bottom"),acts); + + acts = g_slist_prepend(NULL, action_from_string("ToggleShade")); + menu_add_normal(CLIENT_MENU_NAME, CLIENT_SHADE, _("(Un)Shade"), acts); + + acts = g_slist_prepend(NULL, action_from_string("ToggleDecorations")); + menu_add_normal(CLIENT_MENU_NAME, CLIENT_DECORATE, _("Decorate"), acts); + + menu_add_separator(CLIENT_MENU_NAME, -1); + + acts = g_slist_prepend(NULL, action_from_string("KeyboardMove")); + menu_add_normal(CLIENT_MENU_NAME, CLIENT_MOVE, _("Move"), acts); -void *plugin_create() /* TODO: need config */ -{ - ObMenu *m = menu_new_full(NULL, "client-menu", NULL, - client_menu_show, NULL, NULL, NULL, NULL, NULL); - m->plugin = PLUGIN_NAME; - menu_add_entry(m, menu_entry_new_submenu("Send To Workspace", - send_to_menu)); - send_to_menu->parent = m; + acts = g_slist_prepend(NULL, action_from_string("KeyboardResize")); + menu_add_normal(CLIENT_MENU_NAME, CLIENT_RESIZE, _("Resize"), acts); - menu_add_entry(m, menu_entry_new("Iconify", - action_from_string("iconify"))); - menu_add_entry(m, menu_entry_new("Raise", - action_from_string("raise"))); - menu_add_entry(m, menu_entry_new("Lower", - action_from_string("lower"))); - menu_add_entry(m, menu_entry_new("Close", - action_from_string("close"))); - menu_add_entry(m, menu_entry_new("Shade", - action_from_string("toggleshade"))); - menu_add_entry(m, menu_entry_new("Omnipresent", - action_from_string("toggleomnipresent"))); - menu_add_entry(m, menu_entry_new("Decorations", - action_from_string("toggledecorations"))); - menu_add_entry(m, menu_entry_new_submenu("Layers", - layer_menu)); - layer_menu->parent = m; + menu_add_separator(CLIENT_MENU_NAME, -1); - /* send to desktop - iconify - raise - lower - close - kill - shade - omnipresent - decorations - */ - return (void *)m; + acts = g_slist_prepend(NULL, action_from_string("Close")); + menu_add_normal(CLIENT_MENU_NAME, CLIENT_CLOSE, _("Close"), acts); } -void plugin_startup() +void plugin_shutdown() { - ObMenu *t; - /* create a Send To Workspace ObMenu */ - send_to_menu = menu_new_full(NULL, "send-to-workspace", - NULL, NULL, client_send_to_update, - NULL, NULL, NULL, - NULL); - - layer_menu = menu_new(NULL, "layer", NULL); - menu_add_entry(layer_menu, menu_entry_new("Top Layer", - action_from_string("sendtotoplayer"))); - menu_add_entry(layer_menu, menu_entry_new("Normal Layer", - action_from_string("sendtonormallayer"))); - menu_add_entry(layer_menu, menu_entry_new("Bottom Layer", - action_from_string("sendtobottomlayer"))); - - t = (ObMenu *)plugin_create("client_menu"); + menu_free(LAYER_MENU_NAME); + menu_free(SEND_TO_MENU_NAME); + menu_free(CLIENT_MENU_NAME); } -