Resolve gravity coords in menuframe so it can use the widths

This commit is contained in:
Mikael Magnusson 2014-10-06 19:38:51 +02:00
parent 238ab3f742
commit c5c5b7b455
5 changed files with 79 additions and 69 deletions

View file

@ -7,7 +7,7 @@
typedef struct {
gchar *name;
GravityCoord x, y;
GravityPoint position;
ObPlaceMonitor monitor_type;
gint monitor;
gboolean use_position;
@ -37,14 +37,14 @@ static gpointer setup_func(xmlNodePtr node)
if ((n = obt_xml_find_node(node, "position"))) {
if ((c = obt_xml_find_node(n->children, "x"))) {
if (!obt_xml_node_contains(c, "default")) {
config_parse_gravity_coord(c, &o->x);
config_parse_gravity_coord(c, &o->position.x);
x_pos_given = TRUE;
}
}
if (x_pos_given && (c = obt_xml_find_node(n->children, "y"))) {
if (!obt_xml_node_contains(c, "default")) {
config_parse_gravity_coord(c, &o->y);
config_parse_gravity_coord(c, &o->position.y);
o->use_position = TRUE;
}
}
@ -78,71 +78,44 @@ static void free_func(gpointer options)
g_slice_free(Options, o);
}
static void calc_position(Options *o, gint *x, gint *y)
{
gint monitor = -1;
const Rect *area;
if (o->monitor >= 0)
monitor = o->monitor;
else switch (o->monitor_type) {
case OB_PLACE_MONITOR_ANY:
case OB_PLACE_MONITOR_PRIMARY:
monitor = screen_monitor_primary(FALSE);
break;
case OB_PLACE_MONITOR_MOUSE:
monitor = screen_monitor_pointer();
break;
case OB_PLACE_MONITOR_ACTIVE:
monitor = screen_monitor_active();
break;
case OB_PLACE_MONITOR_ALL:
monitor = screen_num_monitors;
break;
default:
g_assert_not_reached();
}
area = screen_physical_area_monitor(monitor);
if (o->x.center)
*x = area->width / 2; /* - client->area.width / 2; */
else {
*x = o->x.pos;
if (o->x.denom)
*x = (*x * area->width) / o->x.denom;
if (o->x.opposite)
*x = area->width /* - frame_size.width */ - *x;
}
if (o->y.center)
*y = area->height / 2; /* - client->area.height / 2; */
else {
*y = o->y.pos;
if (o->y.denom)
*y = (*y * area->height) / o->y.denom;
if (o->y.opposite)
*y = area->height /* - frame_size.height */ - *y;
}
*x += area->x;
*y += area->y;
}
/* Always return FALSE because its not interactive */
static gboolean run_func(ObActionsData *data, gpointer options)
{
Options *o = options;
gint x, y;
GravityPoint position = { 0, };
gint monitor = -1;
if (o->use_position) {
calc_position(o, &x, &y);
if (o->monitor >= 0)
monitor = o->monitor;
else switch (o->monitor_type) {
case OB_PLACE_MONITOR_ANY:
case OB_PLACE_MONITOR_PRIMARY:
monitor = screen_monitor_primary(FALSE);
break;
case OB_PLACE_MONITOR_MOUSE:
monitor = screen_monitor_pointer();
break;
case OB_PLACE_MONITOR_ACTIVE:
monitor = screen_monitor_active();
break;
case OB_PLACE_MONITOR_ALL:
monitor = screen_num_monitors;
break;
default:
g_assert_not_reached();
}
position = o->position;
} else {
x = data->x;
y = data->y;
monitor = screen_num_monitors;
position.x.pos = data->x;
position.y.pos = data->y;
}
/* you cannot call ShowMenu from inside a menu */
if (data->uact != OB_USER_ACTION_MENU_SELECTION && o->name)
menu_show(o->name, x, y, data->button != 0, data->client);
menu_show(o->name, position, monitor, data->button != 0, data->client);
return FALSE;
}

View file

@ -457,7 +457,8 @@ static gboolean menu_hide_delay_func(gpointer data)
return FALSE; /* no repeat */
}
void menu_show(gchar *name, gint x, gint y, gboolean mouse, ObClient *client)
void menu_show(gchar *name, GravityPoint pos, gint monitor,
gboolean mouse, ObClient *client)
{
ObMenu *self;
ObMenuFrame *frame;
@ -479,7 +480,7 @@ void menu_show(gchar *name, gint x, gint y, gboolean mouse, ObClient *client)
menu_clear_pipe_caches();
frame = menu_frame_new(self, 0, client);
if (!menu_frame_show_topmenu(frame, x, y, mouse))
if (!menu_frame_show_topmenu(frame, pos, monitor, mouse))
menu_frame_free(frame);
else {
if (!mouse) {

View file

@ -181,8 +181,8 @@ void menu_clear_pipe_caches(void);
void menu_show_all_shortcuts(ObMenu *self, gboolean show);
void menu_show(gchar *name, gint x, gint y, gboolean mouse,
struct _ObClient *client);
void menu_show(gchar *name, GravityPoint pos, gint monitor,
gboolean mouse, struct _ObClient *client);
gboolean menu_hide_delay_reached(void);
/*! The show function is called right after a menu is shown */

View file

@ -232,10 +232,42 @@ void menu_frame_move(ObMenuFrame *self, gint x, gint y)
XMoveWindow(obt_display, self->window, self->area.x, self->area.y);
}
static void menu_frame_place_topmenu(ObMenuFrame *self, gint *x, gint *y)
static void calc_position(ObMenuFrame *self, GravityPoint *position,
gint *x, gint *y, gint monitor)
{
const Rect *area = screen_physical_area_monitor(monitor);
if (position->x.center)
*x = area->width / 2 - self->area.width / 2;
else {
*x = position->x.pos;
if (position->x.denom)
*x = (*x * area->width) / position->x.denom;
if (position->x.opposite)
*x = area->width - self->area.width - *x;
}
if (position->y.center)
*y = area->height / 2 - self->area.height / 2;
else {
*y = position->y.pos;
if (position->y.denom)
*y = (*y * area->height) / position->y.denom;
if (position->y.opposite)
*y = area->height - self->area.height - *y;
}
*x += area->x;
*y += area->y;
}
static void menu_frame_place_topmenu(ObMenuFrame *self, GravityPoint *pos,
gint *x, gint *y, gint monitor)
{
gint dx, dy;
calc_position(self, pos, x, y, monitor);
if (config_menu_middle) {
gint myx;
@ -989,20 +1021,24 @@ static gboolean menu_frame_show(ObMenuFrame *self)
return TRUE;
}
gboolean menu_frame_show_topmenu(ObMenuFrame *self, gint x, gint y,
gboolean mouse)
gboolean menu_frame_show_topmenu(ObMenuFrame *self, GravityPoint pos,
gint monitor, gboolean mouse)
{
gint px, py;
gint x, y;
if (menu_frame_is_visible(self))
return TRUE;
if (!menu_frame_show(self))
return FALSE;
if (self->menu->place_func)
if (self->menu->place_func) {
x = pos.x.pos;
y = pos.y.pos;
self->menu->place_func(self, &x, &y, mouse, self->menu->data);
else
menu_frame_place_topmenu(self, &x, &y);
} else {
menu_frame_place_topmenu(self, &pos, &x, &y, monitor);
}
menu_frame_move(self, x, y);

View file

@ -120,8 +120,8 @@ void menu_frame_move(ObMenuFrame *self, gint x, gint y);
void menu_frame_move_on_screen(ObMenuFrame *self, gint x, gint y,
gint *dx, gint *dy);
gboolean menu_frame_show_topmenu(ObMenuFrame *self, gint x, gint y,
gboolean mouse);
gboolean menu_frame_show_topmenu(ObMenuFrame *self, GravityPoint pos,
gint monitor, gboolean mouse);
gboolean menu_frame_show_submenu(ObMenuFrame *self, ObMenuFrame *parent,
ObMenuEntryFrame *parent_entry);