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"
6 #include "openbox/config.h"
11 GravityPoint position
;
12 ObPlaceMonitor monitor_type
;
14 gboolean use_position
;
17 static gpointer
setup_func(xmlNodePtr node
);
18 static void free_func(gpointer options
);
19 static gboolean
run_func(ObActionsData
*data
, gpointer options
);
21 void action_showmenu_startup(void)
23 actions_register("ShowMenu", setup_func
, free_func
, run_func
);
26 static gpointer
setup_func(xmlNodePtr node
)
30 gboolean x_pos_given
= FALSE
;
32 o
= g_slice_new0(Options
);
35 if ((n
= obt_xml_find_node(node
, "menu")))
36 o
->name
= obt_xml_node_string(n
);
38 if ((n
= obt_xml_find_node(node
, "position"))) {
39 if ((c
= obt_xml_find_node(n
->children
, "x"))) {
40 if (!obt_xml_node_contains(c
, "default")) {
41 config_parse_gravity_coord(c
, &o
->position
.x
);
46 if (x_pos_given
&& (c
= obt_xml_find_node(n
->children
, "y"))) {
47 if (!obt_xml_node_contains(c
, "default")) {
48 config_parse_gravity_coord(c
, &o
->position
.y
);
49 o
->use_position
= TRUE
;
53 /* unlike client placement, x/y is needed to specify a monitor,
54 * either it's under the mouse or it's in an exact actual position */
55 if (o
->use_position
&& (c
= obt_xml_find_node(n
->children
, "monitor"))) {
56 if (!obt_xml_node_contains(c
, "default")) {
57 gchar
*s
= obt_xml_node_string(c
);
58 if (!g_ascii_strcasecmp(s
, "mouse"))
59 o
->monitor_type
= OB_PLACE_MONITOR_MOUSE
;
60 else if (!g_ascii_strcasecmp(s
, "active"))
61 o
->monitor_type
= OB_PLACE_MONITOR_ACTIVE
;
62 else if (!g_ascii_strcasecmp(s
, "primary"))
63 o
->monitor_type
= OB_PLACE_MONITOR_PRIMARY
;
64 else if (!g_ascii_strcasecmp(s
, "all"))
65 o
->monitor_type
= OB_PLACE_MONITOR_ALL
;
67 o
->monitor
= obt_xml_node_int(c
) - 1;
75 static void free_func(gpointer options
)
79 g_slice_free(Options
, o
);
82 /* Always return FALSE because its not interactive */
83 static gboolean
run_func(ObActionsData
*data
, gpointer options
)
86 GravityPoint position
= { { 0, }, };
89 if (o
->use_position
) {
92 else switch (o
->monitor_type
) {
93 case OB_PLACE_MONITOR_ANY
:
94 case OB_PLACE_MONITOR_PRIMARY
:
95 monitor
= screen_monitor_primary(FALSE
);
97 case OB_PLACE_MONITOR_MOUSE
:
98 monitor
= screen_monitor_pointer();
100 case OB_PLACE_MONITOR_ACTIVE
:
101 monitor
= screen_monitor_active();
103 case OB_PLACE_MONITOR_ALL
:
104 monitor
= screen_num_monitors
;
107 g_assert_not_reached();
110 position
= o
->position
;
113 monitor
= screen_num_monitors
;
114 allmon
= screen_physical_area_monitor(monitor
);
115 position
.x
.pos
= data
->x
- allmon
->x
;
116 position
.y
.pos
= data
->y
- allmon
->y
;
119 /* you cannot call ShowMenu from inside a menu */
120 if (data
->uact
!= OB_USER_ACTION_MENU_SELECTION
&& o
->name
)
121 menu_show(o
->name
, &position
, monitor
,
122 data
->button
!= 0, o
->use_position
, data
->client
);