1 #include "openbox/actions.h"
2 #include "openbox/menu.h"
3 #include "openbox/place.h"
4 #include "openbox/geom.h"
5 #include "openbox/screen.h"
10 GravityPoint position;
11 ObPlaceMonitor monitor_type;
13 gboolean use_position;
16 static gpointer setup_func(xmlNodePtr node);
17 static void free_func(gpointer options);
18 static gboolean run_func(ObActionsData *data, gpointer options);
20 void action_showmenu_startup(void)
22 actions_register("ShowMenu", setup_func, free_func, run_func);
25 static gpointer setup_func(xmlNodePtr node)
29 gboolean x_pos_given = FALSE;
31 o = g_slice_new0(Options);
34 if ((n = obt_xml_find_node(node, "menu")))
35 o->name = obt_xml_node_string(n);
37 if ((n = obt_xml_find_node(node, "position"))) {
38 if ((c = obt_xml_find_node(n->children, "x"))) {
39 if (!obt_xml_node_contains(c, "default")) {
40 config_parse_gravity_coord(c, &o->position.x);
45 if (x_pos_given && (c = obt_xml_find_node(n->children, "y"))) {
46 if (!obt_xml_node_contains(c, "default")) {
47 config_parse_gravity_coord(c, &o->position.y);
48 o->use_position = TRUE;
52 /* unlike client placement, x/y is needed to specify a monitor,
53 * either it's under the mouse or it's in an exact actual position */
54 if (o->use_position && (c = obt_xml_find_node(n->children, "monitor"))) {
55 if (!obt_xml_node_contains(c, "default")) {
56 gchar *s = obt_xml_node_string(c);
57 if (!g_ascii_strcasecmp(s, "mouse"))
58 o->monitor_type = OB_PLACE_MONITOR_MOUSE;
59 else if (!g_ascii_strcasecmp(s, "active"))
60 o->monitor_type = OB_PLACE_MONITOR_ACTIVE;
61 else if (!g_ascii_strcasecmp(s, "primary"))
62 o->monitor_type = OB_PLACE_MONITOR_PRIMARY;
63 else if (!g_ascii_strcasecmp(s, "all"))
64 o->monitor_type = OB_PLACE_MONITOR_ALL;
66 o->monitor = obt_xml_node_int(c) - 1;
74 static void free_func(gpointer options)
78 g_slice_free(Options, o);
81 /* Always return FALSE because its not interactive */
82 static gboolean run_func(ObActionsData *data, gpointer options)
85 GravityPoint position = { 0, };
88 if (o->use_position) {
91 else switch (o->monitor_type) {
92 case OB_PLACE_MONITOR_ANY:
93 case OB_PLACE_MONITOR_PRIMARY:
94 monitor = screen_monitor_primary(FALSE);
96 case OB_PLACE_MONITOR_MOUSE:
97 monitor = screen_monitor_pointer();
99 case OB_PLACE_MONITOR_ACTIVE:
100 monitor = screen_monitor_active();
102 case OB_PLACE_MONITOR_ALL:
103 monitor = screen_num_monitors;
106 g_assert_not_reached();
109 position = o->position;
111 monitor = screen_num_monitors;
112 position.x.pos = data->x;
113 position.y.pos = data->y;
116 /* you cannot call ShowMenu from inside a menu */
117 if (data->uact != OB_USER_ACTION_MENU_SELECTION && o->name)
118 menu_show(o->name, position, monitor,
119 data->button != 0, o->use_position, data->client);