Merge branch 'backport' into work
Conflicts: obt/keyboard.c obt/keyboard.h openbox/event.c openbox/menuframe.c openbox/moveresize.c openbox/openbox.c openbox/screen.c
This commit is contained in:
commit
50d6626811
16 changed files with 249 additions and 173 deletions
|
@ -185,16 +185,24 @@ static void set_modkey_mask(guchar mask, KeySym sym)
|
|||
/* CapsLock, Shift, and Control are special and hard-coded */
|
||||
}
|
||||
|
||||
KeyCode obt_keyboard_keysym_to_keycode(KeySym sym)
|
||||
KeyCode* obt_keyboard_keysym_to_keycode(KeySym sym)
|
||||
{
|
||||
gint i, j;
|
||||
KeyCode *ret;
|
||||
gint i, j, n;
|
||||
|
||||
ret = g_new(KeyCode, 1);
|
||||
n = 0;
|
||||
ret[n] = 0;
|
||||
|
||||
/* go through each keycode and look for the keysym */
|
||||
for (i = min_keycode; i <= max_keycode; ++i)
|
||||
for (j = 0; j < keysyms_per_keycode; ++j)
|
||||
if (sym == keymap[(i-min_keycode) * keysyms_per_keycode + j])
|
||||
return i;
|
||||
return 0;
|
||||
if (sym == keymap[(i-min_keycode) * keysyms_per_keycode + j]) {
|
||||
ret = g_renew(KeyCode, ret, ++n);
|
||||
ret[n-1] = i;
|
||||
ret[n] = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
gchar *obt_keyboard_keycode_to_string(guint keycode)
|
||||
|
|
|
@ -54,9 +54,8 @@ guint obt_keyboard_only_modmasks(guint mask);
|
|||
right keys when there are both. */
|
||||
guint obt_keyboard_modkey_to_modmask(ObtModkeysKey key);
|
||||
|
||||
/*! Convert a KeySym to a KeyCode, because the X function is terrible - says
|
||||
valgrind. */
|
||||
KeyCode obt_keyboard_keysym_to_keycode(KeySym sym);
|
||||
/*! Convert a KeySym to all the KeyCodes which generate it. */
|
||||
KeyCode* obt_keyboard_keysym_to_keycode(KeySym sym);
|
||||
|
||||
/*! Give the string form of a KeyCode */
|
||||
gchar *obt_keyboard_keycode_to_string(guint keycode);
|
||||
|
|
|
@ -146,13 +146,13 @@ static gboolean i_input_func(guint initial_state,
|
|||
{
|
||||
if (e->type == KeyPress) {
|
||||
/* Escape cancels no matter what */
|
||||
if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) {
|
||||
if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) {
|
||||
end_cycle(TRUE, e->xkey.state, options);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* There were no modifiers and they pressed enter */
|
||||
else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN) &&
|
||||
else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) &&
|
||||
!initial_state)
|
||||
{
|
||||
end_cycle(FALSE, e->xkey.state, options);
|
||||
|
|
|
@ -216,13 +216,13 @@ static gboolean i_input_func(guint initial_state,
|
|||
{
|
||||
if (e->type == KeyPress) {
|
||||
/* Escape cancels no matter what */
|
||||
if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) {
|
||||
if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) {
|
||||
end_cycle(TRUE, e->xkey.state, options);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* There were no modifiers and they pressed enter */
|
||||
else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN) &&
|
||||
else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) &&
|
||||
!initial_state)
|
||||
{
|
||||
end_cycle(FALSE, e->xkey.state, options);
|
||||
|
|
|
@ -1751,30 +1751,30 @@ static gboolean event_handle_menu_input(XEvent *ev)
|
|||
else if (ev->type == KeyPress && (state & ~ControlMask) == 0) {
|
||||
frame->got_press = TRUE;
|
||||
|
||||
if (keycode == ob_keycode(OB_KEY_ESCAPE)) {
|
||||
if (ob_keycode_match(keycode, OB_KEY_ESCAPE)) {
|
||||
menu_frame_hide_all();
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
else if (keycode == ob_keycode(OB_KEY_LEFT)) {
|
||||
else if (ob_keycode_match(keycode, OB_KEY_LEFT)) {
|
||||
/* Left goes to the parent menu */
|
||||
if (frame->parent)
|
||||
menu_frame_select(frame, NULL, TRUE);
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
else if (keycode == ob_keycode(OB_KEY_RIGHT)) {
|
||||
else if (ob_keycode_match(keycode, OB_KEY_RIGHT)) {
|
||||
/* Right goes to the selected submenu */
|
||||
if (frame->child) menu_frame_select_next(frame->child);
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
else if (keycode == ob_keycode(OB_KEY_UP)) {
|
||||
else if (ob_keycode_match(keycode, OB_KEY_UP)) {
|
||||
menu_frame_select_previous(frame);
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
else if (keycode == ob_keycode(OB_KEY_DOWN)) {
|
||||
else if (ob_keycode_match(keycode, OB_KEY_DOWN)) {
|
||||
menu_frame_select_next(frame);
|
||||
ret = TRUE;
|
||||
}
|
||||
|
@ -1787,7 +1787,7 @@ static gboolean event_handle_menu_input(XEvent *ev)
|
|||
else if (ev->type == KeyRelease && (state & ~ControlMask) == 0 &&
|
||||
frame->entries && frame->got_press)
|
||||
{
|
||||
if (keycode == ob_keycode(OB_KEY_RETURN)) {
|
||||
if (ob_keycode_match(keycode, OB_KEY_RETURN)) {
|
||||
/* Enter runs the active item or goes into the submenu.
|
||||
Control-Enter runs it without closing the menu. */
|
||||
if (frame->child)
|
||||
|
@ -1885,6 +1885,11 @@ static void event_handle_menu(ObMenuFrame *frame, XEvent *ev)
|
|||
(f = find_active_menu()) && f->selected == e &&
|
||||
e->entry->type != OB_MENU_ENTRY_TYPE_SUBMENU)
|
||||
{
|
||||
ObMenuEntryFrame *u = menu_entry_frame_under(ev->xcrossing.x_root,
|
||||
ev->xcrossing.y_root);
|
||||
/* if we're just going from one entry in the menu to the next,
|
||||
don't unselect stuff first */
|
||||
if (!u || e->frame != u->frame)
|
||||
menu_frame_select(e->frame, NULL, FALSE);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -351,7 +351,7 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c)
|
|||
g_assert(mode == OB_FOCUS_CYCLE_POPUP_MODE_ICONS ||
|
||||
mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST);
|
||||
|
||||
screen_area = screen_physical_area_primary();
|
||||
screen_area = screen_physical_area_primary(FALSE);
|
||||
|
||||
/* get the outside margins */
|
||||
RrMargins(p->a_bg, &ml, &mt, &mr, &mb);
|
||||
|
@ -715,7 +715,7 @@ void focus_cycle_popup_single_show(struct _ObClient *c,
|
|||
g_assert(popup.targets == NULL);
|
||||
|
||||
/* position the popup */
|
||||
a = screen_physical_area_primary();
|
||||
a = screen_physical_area_primary(FALSE);
|
||||
icon_popup_position(single_popup, CenterGravity,
|
||||
a->x + a->width / 2, a->y + a->height / 2);
|
||||
icon_popup_height(single_popup, POPUP_HEIGHT);
|
||||
|
|
|
@ -89,7 +89,7 @@ static void set_curpos(KeyBindingTree *newpos)
|
|||
g_free(oldtext);
|
||||
}
|
||||
|
||||
a = screen_physical_area_primary();
|
||||
a = screen_physical_area_primary(FALSE);
|
||||
popup_position(popup, NorthWestGravity, a->x + 10, a->y + 10);
|
||||
/* 1 second delay for the popup to show */
|
||||
popup_delay_show(popup, G_USEC_PER_SEC, text);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "menu.h"
|
||||
#include "screen.h"
|
||||
#include "actions.h"
|
||||
#include "event.h"
|
||||
#include "grab.h"
|
||||
#include "openbox.h"
|
||||
#include "config.h"
|
||||
|
@ -47,7 +48,8 @@ static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry,
|
|||
ObMenuFrame *frame);
|
||||
static void menu_entry_frame_free(ObMenuEntryFrame *self);
|
||||
static void menu_frame_update(ObMenuFrame *self);
|
||||
static gboolean menu_entry_frame_submenu_timeout(gpointer data);
|
||||
static gboolean menu_entry_frame_submenu_hide_timeout(gpointer data);
|
||||
static gboolean menu_entry_frame_submenu_show_timeout(gpointer data);
|
||||
static void menu_frame_hide(ObMenuFrame *self);
|
||||
|
||||
static Window createWindow(Window parent, gulong mask,
|
||||
|
@ -93,6 +95,7 @@ ObMenuFrame* menu_frame_new(ObMenu *menu, guint show_from, ObClient *client)
|
|||
self->obwin.type = OB_WINDOW_CLASS_MENUFRAME;
|
||||
self->menu = menu;
|
||||
self->selected = NULL;
|
||||
self->open_submenu = NULL;
|
||||
self->client = client;
|
||||
self->direction_right = TRUE;
|
||||
self->show_from = show_from;
|
||||
|
@ -197,6 +200,7 @@ static void menu_entry_frame_free(ObMenuEntryFrame *self)
|
|||
void menu_frame_move(ObMenuFrame *self, gint x, gint y)
|
||||
{
|
||||
RECT_SET_POINT(self->area, x, y);
|
||||
self->monitor = screen_find_monitor_point(x, y);
|
||||
XMoveWindow(obt_display, self->window, self->area.x, self->area.y);
|
||||
}
|
||||
|
||||
|
@ -299,7 +303,7 @@ void menu_frame_move_on_screen(ObMenuFrame *self, gint x, gint y,
|
|||
|
||||
*dx = *dy = 0;
|
||||
|
||||
a = screen_physical_area_monitor(self->monitor);
|
||||
a = screen_physical_area_monitor(screen_find_monitor_point(x, y));
|
||||
|
||||
half = g_list_length(self->entries) / 2;
|
||||
pos = g_list_index(self->entries, self->selected);
|
||||
|
@ -957,24 +961,12 @@ gboolean menu_frame_show_topmenu(ObMenuFrame *self, gint x, gint y,
|
|||
gboolean mouse)
|
||||
{
|
||||
gint px, py;
|
||||
guint i;
|
||||
|
||||
if (menu_frame_is_visible(self))
|
||||
return TRUE;
|
||||
if (!menu_frame_show(self))
|
||||
return FALSE;
|
||||
|
||||
/* find the monitor the menu is on */
|
||||
for (i = 0; i < screen_num_monitors; ++i) {
|
||||
Rect *a = screen_physical_area_monitor(i);
|
||||
gboolean contains = RECT_CONTAINS(*a, x, y);
|
||||
g_free(a);
|
||||
if (contains) {
|
||||
self->monitor = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (self->menu->place_func)
|
||||
self->menu->place_func(self, &x, &y, mouse, self->menu->data);
|
||||
else
|
||||
|
@ -1005,6 +997,7 @@ gboolean menu_frame_show_submenu(ObMenuFrame *self, ObMenuFrame *parent,
|
|||
self->monitor = parent->monitor;
|
||||
self->parent = parent;
|
||||
self->parent_entry = parent_entry;
|
||||
parent->open_submenu = parent_entry;
|
||||
|
||||
/* set up parent's child to be us */
|
||||
if (parent->child)
|
||||
|
@ -1039,6 +1032,7 @@ gboolean menu_frame_show_submenu(ObMenuFrame *self, ObMenuFrame *parent,
|
|||
static void menu_frame_hide(ObMenuFrame *self)
|
||||
{
|
||||
GList *it = g_list_find(menu_frame_visible, self);
|
||||
gulong ignore_start;
|
||||
|
||||
if (!it)
|
||||
return;
|
||||
|
@ -1049,8 +1043,10 @@ static void menu_frame_hide(ObMenuFrame *self)
|
|||
if (self->child)
|
||||
menu_frame_hide(self->child);
|
||||
|
||||
if (self->parent)
|
||||
if (self->parent && self->parent->child == self) {
|
||||
self->parent->child = NULL;
|
||||
self->parent->open_submenu = NULL;
|
||||
}
|
||||
self->parent = NULL;
|
||||
self->parent_entry = NULL;
|
||||
|
||||
|
@ -1062,7 +1058,9 @@ static void menu_frame_hide(ObMenuFrame *self)
|
|||
ungrab_keyboard();
|
||||
}
|
||||
|
||||
ignore_start = event_start_ignore_all_enters();
|
||||
XUnmapWindow(obt_display, self->window);
|
||||
event_end_ignore_all_enters(ignore_start);
|
||||
|
||||
menu_frame_free(self);
|
||||
}
|
||||
|
@ -1074,7 +1072,10 @@ void menu_frame_hide_all(void)
|
|||
if (config_submenu_show_delay) {
|
||||
/* remove any submenu open requests */
|
||||
obt_main_loop_timeout_remove(ob_main_loop,
|
||||
menu_entry_frame_submenu_timeout);
|
||||
menu_entry_frame_submenu_show_timeout);
|
||||
/* remove any submenu close delays */
|
||||
obt_main_loop_timeout_remove(ob_main_loop,
|
||||
menu_entry_frame_submenu_hide_timeout);
|
||||
}
|
||||
if ((it = g_list_last(menu_frame_visible)))
|
||||
menu_frame_hide(it->data);
|
||||
|
@ -1088,8 +1089,13 @@ void menu_frame_hide_all_client(ObClient *client)
|
|||
if (f->client == client) {
|
||||
if (config_submenu_show_delay) {
|
||||
/* remove any submenu open requests */
|
||||
obt_main_loop_timeout_remove(ob_main_loop,
|
||||
menu_entry_frame_submenu_timeout);
|
||||
obt_main_loop_timeout_remove
|
||||
(ob_main_loop,
|
||||
menu_entry_frame_submenu_show_timeout);
|
||||
/* remove any submenu close delays */
|
||||
obt_main_loop_timeout_remove
|
||||
(ob_main_loop,
|
||||
menu_entry_frame_submenu_hide_timeout);
|
||||
}
|
||||
menu_frame_hide(f);
|
||||
}
|
||||
|
@ -1124,7 +1130,6 @@ ObMenuEntryFrame* menu_entry_frame_under(gint x, gint y)
|
|||
|
||||
for (it = frame->entries; it; it = g_list_next(it)) {
|
||||
ObMenuEntryFrame *e = it->data;
|
||||
|
||||
if (RECT_CONTAINS(e->area, x, y)) {
|
||||
ret = e;
|
||||
break;
|
||||
|
@ -1134,7 +1139,15 @@ ObMenuEntryFrame* menu_entry_frame_under(gint x, gint y)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean menu_entry_frame_submenu_timeout(gpointer data)
|
||||
static gboolean menu_entry_frame_submenu_hide_timeout(gpointer data)
|
||||
{
|
||||
g_assert(menu_frame_visible);
|
||||
g_assert(((ObMenuFrame*)data)->parent != NULL);
|
||||
menu_frame_hide((ObMenuFrame*)data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean menu_entry_frame_submenu_show_timeout(gpointer data)
|
||||
{
|
||||
g_assert(menu_frame_visible);
|
||||
menu_entry_frame_show_submenu((ObMenuEntryFrame*)data);
|
||||
|
@ -1155,25 +1168,65 @@ void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry,
|
|||
if (config_submenu_show_delay) {
|
||||
/* remove any submenu open requests */
|
||||
obt_main_loop_timeout_remove(ob_main_loop,
|
||||
menu_entry_frame_submenu_timeout);
|
||||
menu_entry_frame_submenu_show_timeout);
|
||||
}
|
||||
|
||||
if (!entry && self->open_submenu) {
|
||||
/* we moved out of the menu, so move the selection back to the open
|
||||
submenu */
|
||||
entry = self->open_submenu;
|
||||
oldchild = NULL;
|
||||
|
||||
/* remove any submenu close delays */
|
||||
obt_main_loop_timeout_remove(ob_main_loop,
|
||||
menu_entry_frame_submenu_hide_timeout);
|
||||
}
|
||||
|
||||
self->selected = entry;
|
||||
|
||||
if (old)
|
||||
menu_entry_frame_render(old);
|
||||
if (oldchild)
|
||||
|
||||
if (oldchild) {
|
||||
/* there is an open submenu */
|
||||
|
||||
if (config_submenu_show_delay && !immediate) {
|
||||
if (entry == self->open_submenu) {
|
||||
/* we moved onto the entry that has an open submenu, so stop
|
||||
trying to close the submenu */
|
||||
obt_main_loop_timeout_remove
|
||||
(ob_main_loop,
|
||||
menu_entry_frame_submenu_hide_timeout);
|
||||
}
|
||||
else if (old == self->open_submenu) {
|
||||
/* we just moved off the entry with an open submenu, so
|
||||
close the open submenu after a delay */
|
||||
obt_main_loop_timeout_add
|
||||
(ob_main_loop,
|
||||
config_submenu_show_delay * 1000,
|
||||
menu_entry_frame_submenu_hide_timeout,
|
||||
self->child, g_direct_equal,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
menu_frame_hide(oldchild);
|
||||
}
|
||||
|
||||
if (self->selected) {
|
||||
menu_entry_frame_render(self->selected);
|
||||
|
||||
if (self->selected->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) {
|
||||
/* if we've selected a submenu and it wasn't already open, then
|
||||
show it */
|
||||
if (self->selected->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU &&
|
||||
self->selected != self->open_submenu)
|
||||
{
|
||||
if (config_submenu_show_delay && !immediate) {
|
||||
/* initiate a new submenu open request */
|
||||
obt_main_loop_timeout_add(ob_main_loop,
|
||||
obt_main_loop_timeout_add
|
||||
(ob_main_loop,
|
||||
config_submenu_show_delay * 1000,
|
||||
menu_entry_frame_submenu_timeout,
|
||||
menu_entry_frame_submenu_show_timeout,
|
||||
self->selected, g_direct_equal,
|
||||
NULL);
|
||||
} else {
|
||||
|
|
|
@ -53,6 +53,9 @@ struct _ObMenuFrame
|
|||
|
||||
GList *entries;
|
||||
ObMenuEntryFrame *selected;
|
||||
/* if a submenu was selected, then this holds the entry for that submenu
|
||||
until it is closed */
|
||||
ObMenuEntryFrame *open_submenu;
|
||||
|
||||
/* show entries from the menu starting at this index */
|
||||
guint show_from;
|
||||
|
|
|
@ -605,13 +605,13 @@ static void move_with_keys(gint keycode, gint state)
|
|||
gint x, y;
|
||||
ObDirection dir;
|
||||
|
||||
if (keycode == ob_keycode(OB_KEY_RIGHT))
|
||||
if (ob_keycode_match(keycode, OB_KEY_RIGHT))
|
||||
dir = OB_DIRECTION_EAST;
|
||||
else if (keycode == ob_keycode(OB_KEY_LEFT))
|
||||
else if (ob_keycode_match(keycode, OB_KEY_LEFT))
|
||||
dir = OB_DIRECTION_WEST;
|
||||
else if (keycode == ob_keycode(OB_KEY_DOWN))
|
||||
else if (ob_keycode_match(keycode, OB_KEY_DOWN))
|
||||
dir = OB_DIRECTION_SOUTH;
|
||||
else /* if (keycode == ob_keycode(OB_KEY_UP)) */
|
||||
else /* if (ob_keycode_match(keycode, OB_KEY_UP)) */
|
||||
dir = OB_DIRECTION_NORTH;
|
||||
|
||||
client_find_move_directional(moveresize_client, dir, &x, &y);
|
||||
|
@ -627,13 +627,13 @@ static void move_with_keys(gint keycode, gint state)
|
|||
else
|
||||
dist = KEY_DIST;
|
||||
|
||||
if (keycode == ob_keycode(OB_KEY_RIGHT))
|
||||
if (ob_keycode_match(keycode, OB_KEY_RIGHT))
|
||||
dx = dist;
|
||||
else if (keycode == ob_keycode(OB_KEY_LEFT))
|
||||
else if (ob_keycode_match(keycode, OB_KEY_LEFT))
|
||||
dx = -dist;
|
||||
else if (keycode == ob_keycode(OB_KEY_DOWN))
|
||||
else if (ob_keycode_match(keycode, OB_KEY_DOWN))
|
||||
dy = dist;
|
||||
else /* if (keycode == ob_keycode(OB_KEY_UP)) */
|
||||
else /* if (ob_keycode_match(keycode, OB_KEY_UP)) */
|
||||
dy = -dist;
|
||||
}
|
||||
|
||||
|
@ -666,7 +666,7 @@ static void resize_with_keys(gint keycode, gint state)
|
|||
ObDirection dir;
|
||||
|
||||
/* pick the edge if it needs to move */
|
||||
if (keycode == ob_keycode(OB_KEY_RIGHT)) {
|
||||
if (ob_keycode_match(keycode, OB_KEY_RIGHT)) {
|
||||
dir = OB_DIRECTION_EAST;
|
||||
if (key_resize_edge != OB_DIRECTION_WEST &&
|
||||
key_resize_edge != OB_DIRECTION_EAST)
|
||||
|
@ -674,7 +674,7 @@ static void resize_with_keys(gint keycode, gint state)
|
|||
key_resize_edge = OB_DIRECTION_EAST;
|
||||
return;
|
||||
}
|
||||
} else if (keycode == ob_keycode(OB_KEY_LEFT)) {
|
||||
} else if (ob_keycode_match(keycode, OB_KEY_LEFT)) {
|
||||
dir = OB_DIRECTION_WEST;
|
||||
if (key_resize_edge != OB_DIRECTION_WEST &&
|
||||
key_resize_edge != OB_DIRECTION_EAST)
|
||||
|
@ -682,7 +682,7 @@ static void resize_with_keys(gint keycode, gint state)
|
|||
key_resize_edge = OB_DIRECTION_WEST;
|
||||
return;
|
||||
}
|
||||
} else if (keycode == ob_keycode(OB_KEY_UP)) {
|
||||
} else if (ob_keycode_match(keycode, OB_KEY_UP)) {
|
||||
dir = OB_DIRECTION_NORTH;
|
||||
if (key_resize_edge != OB_DIRECTION_NORTH &&
|
||||
key_resize_edge != OB_DIRECTION_SOUTH)
|
||||
|
@ -690,7 +690,7 @@ static void resize_with_keys(gint keycode, gint state)
|
|||
key_resize_edge = OB_DIRECTION_NORTH;
|
||||
return;
|
||||
}
|
||||
} else /* if (keycode == ob_keycode(OB_KEY_DOWN)) */ {
|
||||
} else /* if (ob_keycode_match(keycode, OB_KEY_DOWN)) */ {
|
||||
dir = OB_DIRECTION_SOUTH;
|
||||
if (key_resize_edge != OB_DIRECTION_NORTH &&
|
||||
key_resize_edge != OB_DIRECTION_SOUTH)
|
||||
|
@ -704,13 +704,13 @@ static void resize_with_keys(gint keycode, gint state)
|
|||
if (state & obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SHIFT)) {
|
||||
gint x, y, w, h;
|
||||
|
||||
if (keycode == ob_keycode(OB_KEY_RIGHT))
|
||||
if (ob_keycode_match(keycode, OB_KEY_RIGHT))
|
||||
dir = OB_DIRECTION_EAST;
|
||||
else if (keycode == ob_keycode(OB_KEY_LEFT))
|
||||
else if (ob_keycode_match(keycode, OB_KEY_LEFT))
|
||||
dir = OB_DIRECTION_WEST;
|
||||
else if (keycode == ob_keycode(OB_KEY_DOWN))
|
||||
else if (ob_keycode_match(keycode, OB_KEY_DOWN))
|
||||
dir = OB_DIRECTION_SOUTH;
|
||||
else /* if (keycode == ob_keycode(OB_KEY_UP)) */
|
||||
else /* if (ob_keycode_match(keycode, OB_KEY_UP)) */
|
||||
dir = OB_DIRECTION_NORTH;
|
||||
|
||||
client_find_resize_directional(moveresize_client, key_resize_edge,
|
||||
|
@ -912,16 +912,16 @@ gboolean moveresize_event(XEvent *e)
|
|||
}
|
||||
used = TRUE;
|
||||
} else if (e->type == KeyPress) {
|
||||
if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) {
|
||||
if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) {
|
||||
moveresize_end(TRUE);
|
||||
used = TRUE;
|
||||
} else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN)) {
|
||||
} else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN)) {
|
||||
moveresize_end(FALSE);
|
||||
used = TRUE;
|
||||
} else if (e->xkey.keycode == ob_keycode(OB_KEY_RIGHT) ||
|
||||
e->xkey.keycode == ob_keycode(OB_KEY_LEFT) ||
|
||||
e->xkey.keycode == ob_keycode(OB_KEY_DOWN) ||
|
||||
e->xkey.keycode == ob_keycode(OB_KEY_UP))
|
||||
} else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RIGHT) ||
|
||||
ob_keycode_match(e->xkey.keycode, OB_KEY_LEFT) ||
|
||||
ob_keycode_match(e->xkey.keycode, OB_KEY_DOWN) ||
|
||||
ob_keycode_match(e->xkey.keycode, OB_KEY_UP))
|
||||
{
|
||||
if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_KEYBOARD)) {
|
||||
resize_with_keys(e->xkey.keycode, e->xkey.state);
|
||||
|
|
|
@ -101,7 +101,7 @@ static gboolean reconfigure = FALSE;
|
|||
static gboolean restart = FALSE;
|
||||
static gchar *restart_path = NULL;
|
||||
static Cursor cursors[OB_NUM_CURSORS];
|
||||
static KeyCode keys[OB_NUM_KEYS];
|
||||
static KeyCode *keys[OB_NUM_KEYS];
|
||||
static gint exitcode = 0;
|
||||
static guint remote_control = 0;
|
||||
static gboolean being_replaced = FALSE;
|
||||
|
@ -400,6 +400,16 @@ gint main(gint argc, gchar **argv)
|
|||
event_shutdown(reconfigure);
|
||||
config_shutdown();
|
||||
actions_shutdown(reconfigure);
|
||||
|
||||
/* Free the key codes for built in keys */
|
||||
g_free(keys[OB_KEY_RETURN]);
|
||||
g_free(keys[OB_KEY_ESCAPE]);
|
||||
g_free(keys[OB_KEY_LEFT]);
|
||||
g_free(keys[OB_KEY_RIGHT]);
|
||||
g_free(keys[OB_KEY_UP]);
|
||||
g_free(keys[OB_KEY_DOWN]);
|
||||
g_free(keys[OB_KEY_TAB]);
|
||||
g_free(keys[OB_KEY_SPACE]);
|
||||
} while (reconfigure);
|
||||
}
|
||||
|
||||
|
@ -716,10 +726,14 @@ Cursor ob_cursor(ObCursor cursor)
|
|||
return cursors[cursor];
|
||||
}
|
||||
|
||||
KeyCode ob_keycode(ObKey key)
|
||||
gboolean ob_keycode_match(KeyCode code, ObKey key)
|
||||
{
|
||||
KeyCode *k;
|
||||
|
||||
g_assert(key < OB_NUM_KEYS);
|
||||
return keys[key];
|
||||
for (k = keys[key]; *k; ++k)
|
||||
if (*k == code) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ObState ob_state(void)
|
||||
|
|
|
@ -62,6 +62,6 @@ void ob_exit_with_error(const gchar *msg) G_GNUC_NORETURN;
|
|||
|
||||
Cursor ob_cursor(ObCursor cursor);
|
||||
|
||||
KeyCode ob_keycode(ObKey key);
|
||||
gboolean ob_keycode_match(KeyCode code, ObKey key);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -531,23 +531,23 @@ gboolean prompt_key_event(ObPrompt *self, XEvent *e)
|
|||
if (e->xkey.state != 0 && e->xkey.state != shift_mask)
|
||||
return FALSE;
|
||||
|
||||
if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE))
|
||||
if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE))
|
||||
prompt_cancel(self);
|
||||
else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN) ||
|
||||
e->xkey.keycode == ob_keycode(OB_KEY_SPACE))
|
||||
else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) ||
|
||||
ob_keycode_match(e->xkey.keycode, OB_KEY_SPACE))
|
||||
{
|
||||
prompt_run_callback(self, self->focus->result);
|
||||
}
|
||||
else if (e->xkey.keycode == ob_keycode(OB_KEY_TAB) ||
|
||||
e->xkey.keycode == ob_keycode(OB_KEY_LEFT) ||
|
||||
e->xkey.keycode == ob_keycode(OB_KEY_RIGHT))
|
||||
else if (ob_keycode_match(e->xkey.keycode, OB_KEY_TAB) ||
|
||||
ob_keycode_match(e->xkey.keycode, OB_KEY_LEFT) ||
|
||||
ob_keycode_match(e->xkey.keycode, OB_KEY_RIGHT))
|
||||
{
|
||||
gint i;
|
||||
gboolean left;
|
||||
ObPromptElement *oldfocus;
|
||||
|
||||
left = e->xkey.keycode == ob_keycode(OB_KEY_LEFT) ||
|
||||
(e->xkey.keycode == ob_keycode(OB_KEY_TAB) && shift);
|
||||
left = ob_keycode_match(e->xkey.keycode, OB_KEY_LEFT) ||
|
||||
(ob_keycode_match(e->xkey.keycode, OB_KEY_TAB) && shift);
|
||||
oldfocus = self->focus;
|
||||
|
||||
for (i = 0; i < self->n_buttons; ++i)
|
||||
|
|
|
@ -929,7 +929,7 @@ void screen_show_desktop_popup(guint d)
|
|||
/* 0 means don't show the popup */
|
||||
if (!config_desktop_popup_time) return;
|
||||
|
||||
a = screen_physical_area_primary();
|
||||
a = screen_physical_area_primary(FALSE);
|
||||
pager_popup_position(desktop_popup, CenterGravity,
|
||||
a->x + a->width / 2, a->y + a->height / 2);
|
||||
pager_popup_icon_size_multiplier(desktop_popup,
|
||||
|
@ -1270,19 +1270,6 @@ void screen_install_colormap(ObClient *client, gboolean install)
|
|||
}
|
||||
}
|
||||
|
||||
#define STRUT_LEFT_ON_MONITOR(s, i) \
|
||||
(RANGES_INTERSECT(s->left_start, s->left_end - s->left_start + 1, \
|
||||
monitor_area[i].y, monitor_area[i].height))
|
||||
#define STRUT_RIGHT_ON_MONITOR(s, i) \
|
||||
(RANGES_INTERSECT(s->right_start, s->right_end - s->right_start + 1, \
|
||||
monitor_area[i].y, monitor_area[i].height))
|
||||
#define STRUT_TOP_ON_MONITOR(s, i) \
|
||||
(RANGES_INTERSECT(s->top_start, s->top_end - s->top_start + 1, \
|
||||
monitor_area[i].x, monitor_area[i].width))
|
||||
#define STRUT_BOTTOM_ON_MONITOR(s, i) \
|
||||
(RANGES_INTERSECT(s->bottom_start, s->bottom_end - s->bottom_start + 1, \
|
||||
monitor_area[i].x, monitor_area[i].width))
|
||||
|
||||
typedef struct {
|
||||
guint desktop;
|
||||
StrutPartial *strut;
|
||||
|
@ -1359,7 +1346,7 @@ static void get_xinerama_screens(Rect **xin_areas, guint *nxin)
|
|||
|
||||
void screen_update_areas(void)
|
||||
{
|
||||
guint i, j;
|
||||
guint j;
|
||||
gulong *dims;
|
||||
GList *it;
|
||||
GSList *sit;
|
||||
|
@ -1377,7 +1364,7 @@ void screen_update_areas(void)
|
|||
config_margins.right_start = RECT_TOP(monitor_area[screen_num_monitors]);
|
||||
config_margins.right_end = RECT_BOTTOM(monitor_area[screen_num_monitors]);
|
||||
|
||||
dims = g_new(gulong, 4 * screen_num_desktops * screen_num_monitors);
|
||||
dims = g_new(gulong, 4 * screen_num_desktops);
|
||||
|
||||
RESET_STRUT_LIST(struts_left);
|
||||
RESET_STRUT_LIST(struts_top);
|
||||
|
@ -1423,69 +1410,51 @@ void screen_update_areas(void)
|
|||
VALIDATE_STRUTS(struts_bottom, bottom,
|
||||
monitor_area[screen_num_monitors].height / 2);
|
||||
|
||||
/* set up the work areas to be full screen */
|
||||
for (i = 0; i < screen_num_monitors; ++i)
|
||||
/* set up the work area to be full screen across all monitors */
|
||||
for (j = 0; j < screen_num_desktops; ++j) {
|
||||
dims[(i * screen_num_desktops + j) * 4+0] = monitor_area[i].x;
|
||||
dims[(i * screen_num_desktops + j) * 4+1] = monitor_area[i].y;
|
||||
dims[(i * screen_num_desktops + j) * 4+2] = monitor_area[i].width;
|
||||
dims[(i * screen_num_desktops + j) * 4+3] = monitor_area[i].height;
|
||||
dims[j*4 + 0] =
|
||||
monitor_area[screen_num_monitors].x;
|
||||
dims[j*4 + 1] =
|
||||
monitor_area[screen_num_monitors].y;
|
||||
dims[j*4 + 2] =
|
||||
monitor_area[screen_num_monitors].width;
|
||||
dims[j*4 + 3] =
|
||||
monitor_area[screen_num_monitors].height;
|
||||
}
|
||||
|
||||
/* calculate the work areas from the struts */
|
||||
for (i = 0; i < screen_num_monitors; ++i)
|
||||
/* calculate the work area from the struts */
|
||||
for (j = 0; j < screen_num_desktops; ++j) {
|
||||
gint l = 0, r = 0, t = 0, b = 0;
|
||||
|
||||
/* only add the strut to the area if it touches the monitor */
|
||||
|
||||
for (sit = struts_left; sit; sit = g_slist_next(sit)) {
|
||||
ObScreenStrut *s = sit->data;
|
||||
if ((s->desktop == j || s->desktop == DESKTOP_ALL) &&
|
||||
STRUT_LEFT_ON_MONITOR(s->strut, i))
|
||||
if (s->desktop == j || s->desktop == DESKTOP_ALL)
|
||||
l = MAX(l, s->strut->left);
|
||||
}
|
||||
for (sit = struts_top; sit; sit = g_slist_next(sit)) {
|
||||
ObScreenStrut *s = sit->data;
|
||||
if ((s->desktop == j || s->desktop == DESKTOP_ALL) &&
|
||||
STRUT_TOP_ON_MONITOR(s->strut, i))
|
||||
if (s->desktop == j || s->desktop == DESKTOP_ALL)
|
||||
t = MAX(t, s->strut->top);
|
||||
}
|
||||
for (sit = struts_right; sit; sit = g_slist_next(sit)) {
|
||||
ObScreenStrut *s = sit->data;
|
||||
if ((s->desktop == j || s->desktop == DESKTOP_ALL) &&
|
||||
STRUT_RIGHT_ON_MONITOR(s->strut, i))
|
||||
if (s->desktop == j || s->desktop == DESKTOP_ALL)
|
||||
r = MAX(r, s->strut->right);
|
||||
}
|
||||
for (sit = struts_bottom; sit; sit = g_slist_next(sit)) {
|
||||
ObScreenStrut *s = sit->data;
|
||||
if ((s->desktop == j || s->desktop == DESKTOP_ALL) &&
|
||||
STRUT_BOTTOM_ON_MONITOR(s->strut, i))
|
||||
if (s->desktop == j || s->desktop == DESKTOP_ALL)
|
||||
b = MAX(b, s->strut->bottom);
|
||||
}
|
||||
|
||||
/* if the monitor is not against the edge of the root window,
|
||||
the struts will include the distance from the root window's edge
|
||||
to the monitor, so add that back into the monitor's work area */
|
||||
if (l) l += RECT_LEFT (monitor_area[screen_num_monitors])
|
||||
- RECT_LEFT (monitor_area[i]);
|
||||
if (t) t += RECT_TOP (monitor_area[screen_num_monitors])
|
||||
- RECT_TOP (monitor_area[i]);
|
||||
if (r) r -= RECT_RIGHT (monitor_area[screen_num_monitors])
|
||||
- RECT_RIGHT (monitor_area[i]);
|
||||
if (b) b -= RECT_BOTTOM(monitor_area[screen_num_monitors])
|
||||
- RECT_BOTTOM(monitor_area[i]);
|
||||
|
||||
/* based on these margins, set the work area for the
|
||||
monitor/desktop */
|
||||
dims[(i * screen_num_desktops + j) * 4 + 0] += l;
|
||||
dims[(i * screen_num_desktops + j) * 4 + 1] += t;
|
||||
dims[(i * screen_num_desktops + j) * 4 + 2] -= l + r;
|
||||
dims[(i * screen_num_desktops + j) * 4 + 3] -= t + b;
|
||||
/* based on these margins, set the work area for the desktop */
|
||||
dims[j*4 + 0] += l;
|
||||
dims[j*4 + 1] += t;
|
||||
dims[j*4 + 2] -= l + r;
|
||||
dims[j*4 + 3] -= t + b;
|
||||
}
|
||||
|
||||
/* all the work areas are not used here, only the ones for the first
|
||||
monitor are */
|
||||
/* set the legacy workarea hint to the union of all the monitors */
|
||||
OBT_PROP_SETA32(obt_root(ob_screen), NET_WORKAREA, CARDINAL,
|
||||
dims, 4 * screen_num_desktops);
|
||||
|
||||
|
@ -1724,7 +1693,7 @@ Rect* screen_physical_area_active(void)
|
|||
return screen_physical_area_monitor(screen_monitor_active());
|
||||
}
|
||||
|
||||
guint screen_monitor_primary(void)
|
||||
guint screen_monitor_primary(gboolean fixed)
|
||||
{
|
||||
if (config_primary_monitor_index > 0) {
|
||||
if (config_primary_monitor_index-1 < screen_num_monitors)
|
||||
|
@ -1732,15 +1701,17 @@ guint screen_monitor_primary(void)
|
|||
else
|
||||
return 0;
|
||||
}
|
||||
else if (fixed)
|
||||
return 0;
|
||||
else if (config_primary_monitor == OB_PLACE_MONITOR_ACTIVE)
|
||||
return screen_monitor_active();
|
||||
else /* config_primary_monitor == OB_PLACE_MONITOR_MOUSE */
|
||||
return screen_monitor_pointer();
|
||||
}
|
||||
|
||||
Rect *screen_physical_area_primary(void)
|
||||
Rect *screen_physical_area_primary(gboolean fixed)
|
||||
{
|
||||
return screen_physical_area_monitor(screen_monitor_primary());
|
||||
return screen_physical_area_monitor(screen_monitor_primary(fixed));
|
||||
}
|
||||
|
||||
void screen_set_root_cursor(void)
|
||||
|
@ -1753,17 +1724,21 @@ void screen_set_root_cursor(void)
|
|||
ob_cursor(OB_CURSOR_POINTER));
|
||||
}
|
||||
|
||||
guint screen_monitor_pointer()
|
||||
guint screen_find_monitor_point(guint x, guint y)
|
||||
{
|
||||
Rect mon;
|
||||
gint x, y;
|
||||
if (screen_pointer_pos(&x, &y))
|
||||
RECT_SET(mon, x, y, 1, 1);
|
||||
else
|
||||
RECT_SET(mon, 0, 0, 1, 1);
|
||||
return screen_find_monitor(&mon);
|
||||
}
|
||||
|
||||
guint screen_monitor_pointer()
|
||||
{
|
||||
gint x, y;
|
||||
if (!screen_pointer_pos(&x, &y))
|
||||
x = y = 0;
|
||||
return screen_find_monitor_point(x, y);
|
||||
}
|
||||
|
||||
gboolean screen_pointer_pos(gint *x, gint *y)
|
||||
{
|
||||
Window w;
|
||||
|
|
|
@ -110,10 +110,18 @@ guint screen_monitor_active(void);
|
|||
|
||||
Rect *screen_physical_area_active(void);
|
||||
|
||||
/*! Returns the primary monitor, as specified by the config */
|
||||
guint screen_monitor_primary(void);
|
||||
/*! Returns the primary monitor, as specified by the config.
|
||||
@fixed If TRUE, then this will always return a fixed monitor, otherwise
|
||||
it may change based on where focus is, or other heuristics.
|
||||
*/
|
||||
guint screen_monitor_primary(gboolean fixed);
|
||||
|
||||
Rect *screen_physical_area_primary(void);
|
||||
/*! Returns physical area for the primary monitor, as specified by the config.
|
||||
@fixed If TRUE, then this will always use a fixed monitor as primary,
|
||||
otherwise it may change based on where focus is, or other heuristics.
|
||||
See screen_monitor_primary().
|
||||
*/
|
||||
Rect *screen_physical_area_primary(gboolean fixed);
|
||||
|
||||
/* doesn't include struts which the search area is already outside of when
|
||||
'search' is not NULL */
|
||||
|
@ -134,6 +142,9 @@ gboolean screen_physical_area_monitor_contains(guint head, Rect *search);
|
|||
*/
|
||||
guint screen_find_monitor(Rect *search);
|
||||
|
||||
/*! Finds the monitor which contains the point @x, @y */
|
||||
guint screen_find_monitor_point(guint x, guint y);
|
||||
|
||||
/*! Sets the root cursor. This function decides which cursor to use, but you
|
||||
gotta call it to let it know it should change. */
|
||||
void screen_set_root_cursor(void);
|
||||
|
|
|
@ -73,12 +73,14 @@ static void AddPicture(RrImage *self, RrImagePic ***list, gint *len,
|
|||
/* add the picture as a key to point to this image in the cache */
|
||||
g_hash_table_insert(self->cache->table, (*list)[0], self);
|
||||
|
||||
/*
|
||||
#ifdef DEBUG
|
||||
g_debug("Adding %s picture to the cache:\n "
|
||||
"Image 0x%lx, w %d h %d Hash %u",
|
||||
(*list == self->original ? "ORIGINAL" : "RESIZED"),
|
||||
(gulong)self, pic->width, pic->height, RrImagePicHash(pic));
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
/*! Remove a picture from an Image. This may remove it from the "originals"
|
||||
|
@ -88,6 +90,7 @@ static void RemovePicture(RrImage *self, RrImagePic ***list,
|
|||
{
|
||||
gint j;
|
||||
|
||||
/*
|
||||
#ifdef DEBUG
|
||||
g_debug("Removing %s picture from the cache:\n "
|
||||
"Image 0x%lx, w %d h %d Hash %u",
|
||||
|
@ -95,6 +98,7 @@ static void RemovePicture(RrImage *self, RrImagePic ***list,
|
|||
(gulong)self, (*list)[i]->width, (*list)[i]->height,
|
||||
RrImagePicHash((*list)[i]));
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* remove the picture as a key in the cache */
|
||||
g_hash_table_remove(self->cache->table, (*list)[i]);
|
||||
|
@ -329,10 +333,12 @@ void RrImageRef(RrImage *self)
|
|||
void RrImageUnref(RrImage *self)
|
||||
{
|
||||
if (self && --self->ref == 0) {
|
||||
/*
|
||||
#ifdef DEBUG
|
||||
g_debug("Refcount to 0, removing ALL pictures from the cache:\n "
|
||||
"Image 0x%lx", (gulong)self);
|
||||
#endif
|
||||
*/
|
||||
while (self->n_original > 0)
|
||||
RemovePicture(self, &self->original, 0, &self->n_original);
|
||||
while (self->n_resized > 0)
|
||||
|
@ -352,10 +358,12 @@ void RrImageAddPicture(RrImage *self, RrPixel32 *data, gint w, gint h)
|
|||
/* make sure we don't already have this size.. */
|
||||
for (i = 0; i < self->n_original; ++i)
|
||||
if (self->original[i]->width == w && self->original[i]->height == h) {
|
||||
/*
|
||||
#ifdef DEBUG
|
||||
g_debug("Found duplicate ORIGINAL image:\n "
|
||||
"Image 0x%lx, w %d h %d", (gulong)self, w, h);
|
||||
#endif
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue