all repos — openbox @ 50d662681160c309ea86268c0d05794b87b75593

openbox fork - make it a bit more like ryudo

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
Dana Jansens danakj@orodu.net
commit

50d662681160c309ea86268c0d05794b87b75593

parent

a93b00a5e93281c7c2c31112f0b6b827d605a19d

M obt/keyboard.cobt/keyboard.c

@@ -185,16 +185,24 @@

/* 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)
M obt/keyboard.hobt/keyboard.h

@@ -54,9 +54,8 @@ /*! Get the modifier masks for a modifier key. This includes both the left and

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);
M openbox/actions/cyclewindows.copenbox/actions/cyclewindows.c

@@ -146,13 +146,13 @@ gboolean *used)

{ 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);
M openbox/actions/directionalwindows.copenbox/actions/directionalwindows.c

@@ -216,13 +216,13 @@ gboolean *used)

{ 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);
M openbox/event.copenbox/event.c

@@ -1751,30 +1751,30 @@ /* Allow control while going thru the menu */

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 @@ Allow ControlMask only, and don't bother if the menu is empty */

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,7 +1885,12 @@ if ((e = g_hash_table_lookup(menu_frame_map, &ev->xcrossing.window)) &&

(f = find_active_menu()) && f->selected == e && e->entry->type != OB_MENU_ENTRY_TYPE_SUBMENU) { - menu_frame_select(e->frame, NULL, FALSE); + 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; }
M openbox/focus_cycle_popup.copenbox/focus_cycle_popup.c

@@ -351,7 +351,7 @@

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 @@ dock_windows, desktop_windows);

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);
M openbox/keyboard.copenbox/keyboard.c

@@ -89,7 +89,7 @@ text = g_strconcat(text, " - ", it->data, NULL);

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);
M openbox/menuframe.copenbox/menuframe.c

@@ -22,6 +22,7 @@ #include "client.h"

#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 @@ self = g_new0(ObMenuFrame, 1);

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 @@

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 @@ gint pos, half;

*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,23 +961,11 @@ 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);

@@ -1005,6 +997,7 @@

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 @@

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 @@

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 @@ ungrab_pointer();

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 @@

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 @@ ObMenuFrame *f = it->data;

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 @@ y -= ob_rr_theme->mbwidth + frame->area.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 @@ }

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,27 +1168,67 @@

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) - menu_frame_hide(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, - config_submenu_show_delay * 1000, - menu_entry_frame_submenu_timeout, - self->selected, g_direct_equal, - NULL); + obt_main_loop_timeout_add + (ob_main_loop, + config_submenu_show_delay * 1000, + menu_entry_frame_submenu_show_timeout, + self->selected, g_direct_equal, + NULL); } else { menu_entry_frame_show_submenu(self->selected); }
M openbox/menuframe.hopenbox/menuframe.h

@@ -53,6 +53,9 @@ ObMenuFrame *child;

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;
M openbox/moveresize.copenbox/moveresize.c

@@ -605,13 +605,13 @@ if (state & obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SHIFT)) {

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 @@ }

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 @@ gint resist = 0;

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 @@ {

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 @@ {

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 @@ {

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 @@ /* shift means jump to edge */

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 @@ do_resize();

} 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);
M openbox/openbox.copenbox/openbox.c

@@ -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 @@ sn_shutdown(reconfigure);

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 @@ g_assert(cursor < OB_NUM_CURSORS);

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)
M openbox/openbox.hopenbox/openbox.h

@@ -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
M openbox/prompt.copenbox/prompt.c

@@ -531,23 +531,23 @@ /* only accept shift */

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)
M openbox/screen.copenbox/screen.c

@@ -929,7 +929,7 @@

/* 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 @@ obt_display_ignore_errors(FALSE);

} } -#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 @@ }

void screen_update_areas(void) { - guint i, j; + guint j; gulong *dims; GList *it; GSList *sit;

@@ -1377,7 +1364,7 @@ config_margins.left_end = RECT_BOTTOM(monitor_area[screen_num_monitors]);

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 @@ monitor_area[screen_num_monitors].height / 2);

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) - 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; - } + /* set up the work area to be full screen across all monitors */ + for (j = 0; j < screen_num_desktops; ++j) { + 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) - for (j = 0; j < screen_num_desktops; ++j) { - gint l = 0, r = 0, t = 0, b = 0; + /* 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) + 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) + 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) + 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) + b = MAX(b, s->strut->bottom); + } - 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)) - 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)) - 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)) - 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)) - b = MAX(b, s->strut->bottom); - } + /* 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; + } - /* 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; - } - - /* 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 @@ {

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 @@ return config_primary_monitor_index - 1;

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,15 +1724,19 @@ XDefineCursor(obt_display, obt_root(ob_screen),

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); + RECT_SET(mon, x, y, 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)
M openbox/screen.hopenbox/screen.h

@@ -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 */

@@ -133,6 +141,9 @@ area of the part of the rectable on each monitor. The number of the

monitor containing the greatest area of the rectangle is returned. */ 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. */
M render/image.crender/image.c

@@ -73,12 +73,14 @@

/* 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 @@ gint i, gint *len)

{ 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 @@ (*list == self->original ? "ORIGINAL" : "RESIZED"),

(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 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 @@

/* 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; }