From 9e9a7e124d1a80579281c5ab2ffc3574f38f9eba Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 09:46:07 -0500 Subject: allow dialog windows to be fullscreened, kpdf does this --- openbox/client.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'openbox') diff --git a/openbox/client.c b/openbox/client.c index d0fed545..1e2040fd 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -1634,11 +1634,16 @@ void client_setup_decor_and_functions(ObClient *self, gboolean reconfig) switch (self->type) { case OB_CLIENT_TYPE_NORMAL: /* normal windows retain all of the possible decorations and - functionality, and are the only windows that you can fullscreen */ + functionality, and can be fullscreen */ self->functions |= OB_CLIENT_FUNC_FULLSCREEN; break; case OB_CLIENT_TYPE_DIALOG: + /* sometimes apps make dialog windows fullscreen for some reason (for + e.g. kpdf does this..) */ + self->functions |= OB_CLIENT_FUNC_FULLSCREEN; + break; + case OB_CLIENT_TYPE_UTILITY: /* these windows don't have anything added or removed by default */ break; -- cgit v1.2.3 From 44ee90c94623d37b3de3767233bc9cd38b670d34 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 10:00:58 -0500 Subject: Bug#: 3328 - remove top border for maxed undecorated windows --- openbox/frame.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'openbox') diff --git a/openbox/frame.c b/openbox/frame.c index b10f793b..b49139ac 100644 --- a/openbox/frame.c +++ b/openbox/frame.c @@ -377,10 +377,12 @@ void frame_adjust_area(ObFrame *self, gboolean moved, STRUT_SET(self->size, self->cbwidth_l + (!self->max_horz ? self->bwidth : 0), - self->cbwidth_t + self->bwidth, + self->cbwidth_t + + (!self->max_horz || !self->max_vert || + !self->client->undecorated ? self->bwidth : 0), self->cbwidth_r + (!self->max_horz ? self->bwidth : 0), self->cbwidth_b + - (!self->max_horz || !self->max_vert ? self->bwidth : 0)); + (!self->max_horz || !self->max_vert ? self->bwidth : 0)); if (self->decorations & OB_FRAME_DECOR_TITLEBAR) self->size.top += ob_rr_theme->title_height + self->bwidth; -- cgit v1.2.3 From 8a51893e8bf2192eec69eeed9bc49beb78e34312 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 11:21:00 -0500 Subject: Revert "fix for xkb weirdness, to fix a bug introduced in 3.4.3, where releasing the super mod key would not end interactive actions." This reverts commit 47e7aa82dc9f390c809151f87c81f33b5b408221. This is an XKB problem, and it needs to be properly resolved with XKB functions --- openbox/modkeys.c | 54 ++++++++++-------------------------------------------- 1 file changed, 10 insertions(+), 44 deletions(-) (limited to 'openbox') diff --git a/openbox/modkeys.c b/openbox/modkeys.c index c993cfc1..9e8da321 100644 --- a/openbox/modkeys.c +++ b/openbox/modkeys.c @@ -35,21 +35,7 @@ static void set_modkey_mask(guchar mask, KeySym sym); -/* This is 8 lists of keycodes that are bound to the given mod mask. - If contains more than the one given to us by X cuz XKB is weird apparently. - We will look up all keycodes for a given keysym that is bound to the mask, - and add them all here. - - With XKB, you can have a keycode bound to a modifier that isn't in the - modifier map somehow. So this means that when we try translate from the - KeyRelease to a mod mask, we are unable to. So this array stores *all* - the KeyCodes for each KeySym for each KeyCode bound to a mod mask. - Confused? Haha... - - ModMask -> n KeyCodes -> n*m KeySyms (up to m for each KeyCode) -> - n*m*p KeyCodes (up to p for each KeySym) -*/ -static GArray *modmap[NUM_MASKS]; +static XModifierKeymap *modmap; static KeySym *keymap; static gint min_keycode, max_keycode, keysyms_per_keycode; /* This is a bitmask of the different masks for each modifier key */ @@ -62,15 +48,14 @@ static gboolean hyper_l = FALSE; void modkeys_startup(gboolean reconfigure) { - static XModifierKeymap *xmodmap; - gint i, j, k, l, m; + gint i, j, k; /* reset the keys to not be bound to any masks */ for (i = 0; i < OB_MODKEY_NUM_KEYS; ++i) modkeys_keys[i] = 0; - xmodmap = XGetModifierMapping(ob_display); - g_assert(xmodmap->max_keypermod > 0); + modmap = XGetModifierMapping(ob_display); + g_assert(modmap->max_keypermod > 0); XDisplayKeycodes(ob_display, &min_keycode, &max_keycode); keymap = XGetKeyboardMapping(ob_display, min_keycode, @@ -81,31 +66,17 @@ void modkeys_startup(gboolean reconfigure) /* go through each of the modifier masks (eg ShiftMask, CapsMask...) */ for (i = 0; i < NUM_MASKS; ++i) { - /* reset the modmap list */ - modmap[i] = g_array_new(FALSE, FALSE, sizeof(KeyCode)); - /* go through each keycode that is bound to the mask */ - for (j = 0; j < xmodmap->max_keypermod; ++j) { + for (j = 0; j < modmap->max_keypermod; ++j) { KeySym sym; /* get a keycode that is bound to the mask (i) */ - KeyCode keycode = xmodmap->modifiermap[i*xmodmap->max_keypermod+j]; + KeyCode keycode = modmap->modifiermap[i*modmap->max_keypermod + j]; if (keycode) { /* go through each keysym bound to the given keycode */ for (k = 0; k < keysyms_per_keycode; ++k) { sym = keymap[(keycode-min_keycode) * keysyms_per_keycode + k]; if (sym != NoSymbol) { - /* find all keycodes for the given keysym */ - for (l = min_keycode; l <= max_keycode; ++l) - for (m = 0; m < keysyms_per_keycode; ++m) - if (keymap[(l-min_keycode) * - keysyms_per_keycode + m] == sym) - { - /* add all keycodes for the keysym to our - modmap */ - g_array_append_val(modmap[i], l); - } - /* bind the key to the mask (e.g. Alt_L => Mod1Mask) */ set_modkey_mask(nth_mask(i), sym); } @@ -118,22 +89,17 @@ void modkeys_startup(gboolean reconfigure) modkeys_keys[OB_MODKEY_KEY_CAPSLOCK] = LockMask; modkeys_keys[OB_MODKEY_KEY_SHIFT] = ShiftMask; modkeys_keys[OB_MODKEY_KEY_CONTROL] = ControlMask; - - XFreeModifiermap(xmodmap); } void modkeys_shutdown(gboolean reconfigure) { - guint i; - - for (i = 0; i < NUM_MASKS; ++i) - g_array_free(modmap[i], TRUE); + XFreeModifiermap(modmap); XFree(keymap); } guint modkeys_keycode_to_mask(guint keycode) { - guint i, j; + gint i, j; guint mask = 0; if (keycode == NoSymbol) return 0; @@ -141,9 +107,9 @@ guint modkeys_keycode_to_mask(guint keycode) /* go through each of the modifier masks (eg ShiftMask, CapsMask...) */ for (i = 0; i < NUM_MASKS; ++i) { /* go through each keycode that is bound to the mask */ - for (j = 0; j < modmap[i]->len; ++j) { + for (j = 0; j < modmap->max_keypermod; ++j) { /* compare with a keycode that is bound to the mask (i) */ - if (g_array_index(modmap[i], KeyCode, j) == keycode) + if (modmap->modifiermap[i*modmap->max_keypermod + j] == keycode) mask |= nth_mask(i); } } -- cgit v1.2.3 From 5a468756c07a43e0ee7fa4e406847c86db09834a Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 11:42:09 -0500 Subject: reconfigure openbox when the input mapping changes, eg. keyboard layout or modifier map --- openbox/event.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'openbox') diff --git a/openbox/event.c b/openbox/event.c index 5e44bc9f..41bcd350 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -619,6 +619,11 @@ static void event_process(const XEvent *ec, gpointer data) event_handle_root(e); else if (e->type == MapRequest) client_manage(window); + else if (e->type == MappingNotify) { + /* keyboard layout changes, reconfigure openbox. need to restart the + modkeys system, but also to reload the key bindings. */ + ob_reconfigure(); + } else if (e->type == ClientMessage) { /* This is for _NET_WM_REQUEST_FRAME_EXTENTS messages. They come for windows that are not managed yet. */ -- cgit v1.2.3 From 162a97e158e0dfa774754aee5198786907f9453b Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 13:05:11 -0500 Subject: XKB modifiers are strange things, and i don't know how to read them properly in modkeys.c and convert it all to the x core stuff. so we use this to get the state of the modifiers, otherwise we end up missing them sometimes (like on PPC) --- openbox/event.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'openbox') diff --git a/openbox/event.c b/openbox/event.c index 41bcd350..0c97bd93 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -247,6 +247,10 @@ static void event_set_curtime(XEvent *e) static void event_hack_mods(XEvent *e) { +#ifdef XKB + XkbStateRec xkb_state; +#endif + switch (e->type) { case ButtonPress: case ButtonRelease: @@ -256,10 +260,22 @@ static void event_hack_mods(XEvent *e) e->xkey.state = modkeys_only_modifier_masks(e->xkey.state); break; case KeyRelease: - e->xkey.state = modkeys_only_modifier_masks(e->xkey.state); - /* remove from the state the mask of the modifier key being released, - if it is a modifier key being released that is */ - e->xkey.state &= ~modkeys_keycode_to_mask(e->xkey.keycode); +#ifdef XKB + /* If XKB is present, then the modifiers are all strange from its + magic. Our X core protocol stuff won't work, so we use this to + find what the modifier state is instead. */ + if (XkbGetState(ob_display, XkbUseCoreKbd, &xkb_state) == Success) { + e->xkey.state = xkb_state.compat_state; + break; + } + else +#endif + { + e->xkey.state = modkeys_only_modifier_masks(e->xkey.state); + /* remove from the state the mask of the modifier key being + released, if it is a modifier key being released that is */ + e->xkey.state &= ~modkeys_keycode_to_mask(e->xkey.keycode); + } break; case MotionNotify: e->xmotion.state = modkeys_only_modifier_masks(e->xmotion.state); -- cgit v1.2.3 From b447f16f6080e1a92c3ea6a5848609a7a96ea3ce Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 13:06:37 -0500 Subject: code clean up --- openbox/event.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'openbox') diff --git a/openbox/event.c b/openbox/event.c index 0c97bd93..e3214a7a 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -264,10 +264,8 @@ static void event_hack_mods(XEvent *e) /* If XKB is present, then the modifiers are all strange from its magic. Our X core protocol stuff won't work, so we use this to find what the modifier state is instead. */ - if (XkbGetState(ob_display, XkbUseCoreKbd, &xkb_state) == Success) { + if (XkbGetState(ob_display, XkbUseCoreKbd, &xkb_state) == Success) e->xkey.state = xkb_state.compat_state; - break; - } else #endif { -- cgit v1.2.3 From 0ce14a727968736e57fb3fabba3794b46903875f Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 14:40:58 -0500 Subject: fix a focus race condition in two ways: 1. when focusing a window, ignore any enter events up until the serial of the X event causing the focus, not up until the last thing sent to the server. if we get 2 enters very quickly, then we don't want to ignore the second one just because we are focusing the first window. 2. there is a race if you check (focus_client != d->client) in the delay_focus_func, because the current focused window might change by the time this focus_client would take effect, so don't check that. --- openbox/event.c | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) (limited to 'openbox') diff --git a/openbox/event.c b/openbox/event.c index e3214a7a..03229117 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -91,6 +91,7 @@ static void event_handle_dockapp(ObDockApp *app, XEvent *e); static void event_handle_client(ObClient *c, XEvent *e); static void event_handle_user_input(ObClient *client, XEvent *e); static gboolean is_enter_focus_event_ignored(XEvent *e); +static void event_ignore_enter_range(gulong start, gulong end); static void focus_delay_dest(gpointer data); static gboolean focus_delay_cmp(gconstpointer d1, gconstpointer d2); @@ -99,6 +100,8 @@ static void focus_delay_client_dest(ObClient *client, gpointer data); Time event_curtime = CurrentTime; Time event_last_user_time = CurrentTime; +/*! The serial of the current X event */ +gulong event_curserial; static gboolean focus_left_screen = FALSE; /*! A list of ObSerialRanges which are to be ignored for mouse enter events */ @@ -243,6 +246,7 @@ static void event_set_curtime(XEvent *e) event_last_user_time = CurrentTime; event_curtime = t; + event_curserial = 0; } static void event_hack_mods(XEvent *e) @@ -479,6 +483,7 @@ static void event_process(const XEvent *ec, gpointer data) } event_set_curtime(e); + event_curserial = e->xany.serial; event_hack_mods(e); if (event_ignore(e, client)) { if (ed) @@ -1010,18 +1015,23 @@ static void event_handle_client(ObClient *client, XEvent *e) is_enter_focus_event_ignored(e)) { ob_debug_type(OB_DEBUG_FOCUS, - "%sNotify mode %d detail %d on %lx IGNORED\n", + "%sNotify mode %d detail %d serial %lu on %lx " + "IGNORED\n", (e->type == EnterNotify ? "Enter" : "Leave"), e->xcrossing.mode, - e->xcrossing.detail, client?client->window:0); + e->xcrossing.detail, + e->xcrossing.serial, + client?client->window:0); } else { ob_debug_type(OB_DEBUG_FOCUS, - "%sNotify mode %d detail %d on %lx, " + "%sNotify mode %d detail %d serial %lu on %lx, " "focusing window\n", (e->type == EnterNotify ? "Enter" : "Leave"), e->xcrossing.mode, - e->xcrossing.detail, (client?client->window:0)); + e->xcrossing.detail, + e->xcrossing.serial, + (client?client->window:0)); if (config_focus_follow) event_enter_client(client); } @@ -1864,10 +1874,8 @@ static gboolean focus_delay_func(gpointer data) if (menu_frame_visible || moveresize_in_progress) return FALSE; event_curtime = d->time; - if (focus_client != d->client) { - if (client_focus(d->client) && config_focus_raise) - stacking_raise(CLIENT_AS_WINDOW(d->client)); - } + if (client_focus(d->client) && config_focus_raise) + stacking_raise(CLIENT_AS_WINDOW(d->client)); event_curtime = old; return FALSE; /* no repeat */ } @@ -1878,35 +1886,44 @@ static void focus_delay_client_dest(ObClient *client, gpointer data) client, FALSE); } -void event_halt_focus_delay(void) +void event_halt_focus_delay(gulong serial) { - /* ignore all enter events up till now */ - event_end_ignore_all_enters(1); + /* ignore all enter events up till the event which caused this to occur */ + if (event_curserial) event_ignore_enter_range(1, event_curserial); ob_main_loop_timeout_remove(ob_main_loop, focus_delay_func); } gulong event_start_ignore_all_enters(void) { + /* increment the serial so we don't ignore events we weren't meant to */ XSync(ob_display, FALSE); return LastKnownRequestProcessed(ob_display); } -void event_end_ignore_all_enters(gulong start) +static void event_ignore_enter_range(gulong start, gulong end) { ObSerialRange *r; g_assert(start != 0); - XSync(ob_display, FALSE); + g_assert(end != 0); r = g_new(ObSerialRange, 1); r->start = start; - r->end = LastKnownRequestProcessed(ob_display); + r->end = end; ignore_serials = g_slist_prepend(ignore_serials, r); + ob_debug_type(OB_DEBUG_FOCUS, "ignoring enters from %lu until %lu\n", + r->start, r->end); + /* increment the serial so we don't ignore events we weren't meant to */ XSync(ob_display, FALSE); } +void event_end_ignore_all_enters(gulong start) +{ + event_ignore_enter_range(start, LastKnownRequestProcessed(ob_display)); +} + static gboolean is_enter_focus_event_ignored(XEvent *e) { GSList *it, *next; -- cgit v1.2.3 From 1789d4564514c4cefe3d2e9d2b7b65119784b53c Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 15:18:04 -0500 Subject: fix a warning from crappy libc apis --- openbox/openbox.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'openbox') diff --git a/openbox/openbox.c b/openbox/openbox.c index 6f47fbd0..ff226af4 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -512,7 +512,9 @@ static void remove_args(gint *argc, gchar **argv, gint index, gint num) static void parse_env() { /* unset this so we don't pass it on unknowingly */ - putenv("DESKTOP_STARTUP_ID"); + gchar *s = g_strdup("DESKTOP_STARTUP_ID"); + putenv(s); + g_free(s); } static void parse_args(gint *argc, gchar **argv) -- cgit v1.2.3 From abc67cbdc1c1e61e074f8f312eaecb357cd0aa5c Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 15:28:26 -0500 Subject: make it possible to temporarily raise a window to the top, and restore it. also fix the return val for window_layer. --- openbox/actions/lower.c | 1 + openbox/actions/raise.c | 1 + openbox/client.h | 1 + openbox/stacking.c | 36 ++++++++++++++++++++++++++++++++++++ openbox/stacking.h | 21 ++++++++++++++------- openbox/window.c | 2 +- openbox/window.h | 4 +++- 7 files changed, 57 insertions(+), 9 deletions(-) (limited to 'openbox') diff --git a/openbox/actions/lower.c b/openbox/actions/lower.c index 3a214ea7..d34e933b 100644 --- a/openbox/actions/lower.c +++ b/openbox/actions/lower.c @@ -1,5 +1,6 @@ #include "openbox/actions.h" #include "openbox/stacking.h" +#include "openbox/window.h" static gboolean run_func(ObActionsData *data, gpointer options); diff --git a/openbox/actions/raise.c b/openbox/actions/raise.c index 5dfe281a..6837bce2 100644 --- a/openbox/actions/raise.c +++ b/openbox/actions/raise.c @@ -1,5 +1,6 @@ #include "openbox/actions.h" #include "openbox/stacking.h" +#include "openbox/window.h" static gboolean run_func(ObActionsData *data, gpointer options); diff --git a/openbox/client.h b/openbox/client.h index b4b165f8..e83a6b7a 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -24,6 +24,7 @@ #include "mwm.h" #include "geom.h" #include "stacking.h" +#include "window.h" #include "render/color.h" #include diff --git a/openbox/stacking.c b/openbox/stacking.c index b23e6eac..bb8975d4 100644 --- a/openbox/stacking.c +++ b/openbox/stacking.c @@ -105,6 +105,42 @@ static void do_restack(GList *wins, GList *before) stacking_set_list(); } +void stacking_temp_raise(ObWindow *window) +{ + Window win[2]; + GList *it; + + /* don't use this for internal windows..! it would lower them.. */ + g_assert(window_layer(window) < OB_STACKING_LAYER_INTERNAL); + + /* find the window to drop it underneath */ + win[0] = screen_support_win; + for (it = stacking_list; it; it = g_list_next(it)) { + ObWindow *w = it->data; + if (window_layer(w) >= OB_STACKING_LAYER_INTERNAL) + win[0] = window_top(w); + else + break; + } + + win[1] = window_top(window); + XRestackWindows(ob_display, win, 2); +} + +void stacking_restore() +{ + Window *win; + GList *it; + gint i; + + win = g_new(Window, g_list_length(stacking_list) + 1); + win[0] = screen_support_win; + for (i = 1, it = stacking_list; it; ++i, it = g_list_next(it)) + win[i] = window_top(it->data); + XRestackWindows(ob_display, win, i); + g_free(win); +} + static void do_raise(GList *wins) { GList *it; diff --git a/openbox/stacking.h b/openbox/stacking.h index ac9c8239..e226f36f 100644 --- a/openbox/stacking.h +++ b/openbox/stacking.h @@ -20,11 +20,12 @@ #ifndef __stacking_h #define __stacking_h -#include "window.h" - #include #include +struct _ObWindow; +struct _ObClient; + /*! The possible stacking layers a client window can be a part of */ typedef enum { OB_STACKING_LAYER_INVALID, @@ -44,21 +45,27 @@ extern GList *stacking_list; stacking_list */ void stacking_set_list(); -void stacking_add(ObWindow *win); -void stacking_add_nonintrusive(ObWindow *win); +void stacking_add(struct _ObWindow *win); +void stacking_add_nonintrusive(struct _ObWindow *win); #define stacking_remove(win) stacking_list = g_list_remove(stacking_list, win); /*! Raises a window above all others in its stacking layer */ -void stacking_raise(ObWindow *window); +void stacking_raise(struct _ObWindow *window); + +/*! Temporarily raises a window above all others */ +void stacking_temp_raise(struct _ObWindow *window); + +/*! Restores any temporarily raised windows to their correct place */ +void stacking_restore(); /*! Lowers a window below all others in its stacking layer */ -void stacking_lower(ObWindow *window); +void stacking_lower(struct _ObWindow *window); /*! Moves a window below another if its in the same layer. This function does not enforce stacking rules IRT transients n such, and so it should really ONLY be used to restore stacking orders from saved sessions */ -void stacking_below(ObWindow *window, ObWindow *below); +void stacking_below(struct _ObWindow *window, struct _ObWindow *below); /*! Restack a window based upon a sibling (or all windows) in various ways. @param client The client to be restacked diff --git a/openbox/window.c b/openbox/window.c index 19b39c09..c5e6a4ea 100644 --- a/openbox/window.c +++ b/openbox/window.c @@ -63,7 +63,7 @@ Window window_top(ObWindow *self) return None; } -Window window_layer(ObWindow *self) +ObStackingLayer window_layer(ObWindow *self) { switch (self->type) { case Window_Menu: diff --git a/openbox/window.h b/openbox/window.h index ef29edd7..aaf83995 100644 --- a/openbox/window.h +++ b/openbox/window.h @@ -19,6 +19,8 @@ #ifndef __window_h #define __window_h +#include "stacking.h" + #include #include @@ -74,6 +76,6 @@ void window_startup(gboolean reconfig); void window_shutdown(gboolean reconfig); Window window_top(ObWindow *self); -Window window_layer(ObWindow *self); +ObStackingLayer window_layer(ObWindow *self); #endif -- cgit v1.2.3 From 746015e88c51dda43b26f35abc25050c502d319b Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 15:36:31 -0500 Subject: make backport closer to 3.4-working for merging purposes --- openbox/actions/cyclewindows.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'openbox') diff --git a/openbox/actions/cyclewindows.c b/openbox/actions/cyclewindows.c index 965ac993..285df370 100644 --- a/openbox/actions/cyclewindows.c +++ b/openbox/actions/cyclewindows.c @@ -178,8 +178,7 @@ static void end_cycle(gboolean cancel, guint state, Options *o) TRUE, cancel); cycling = FALSE; - if (ft) { + if (ft) actions_run_acts(o->actions, OB_USER_ACTION_KEYBOARD_KEY, state, -1, -1, 0, OB_FRAME_CONTEXT_NONE, ft); - } } -- cgit v1.2.3 From ea371936cec5f1e7f0eaed698b2cff6fab42f210 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 16:11:51 -0500 Subject: let you raise the focus target temporarily during focus cycling, with the option. also a new option lets you turn off the indicator bar --- openbox/actions/cyclewindows.c | 33 +++++++++++++++++++++++++-------- openbox/actions/directionalwindows.c | 33 +++++++++++++++++++++++++-------- openbox/focus_cycle.c | 13 +++++++------ openbox/focus_cycle.h | 4 +++- openbox/focus_cycle_indicator.c | 12 ++++++++++-- 5 files changed, 70 insertions(+), 25 deletions(-) (limited to 'openbox') diff --git a/openbox/actions/cyclewindows.c b/openbox/actions/cyclewindows.c index 285df370..059db93f 100644 --- a/openbox/actions/cyclewindows.c +++ b/openbox/actions/cyclewindows.c @@ -1,4 +1,6 @@ #include "openbox/actions.h" +#include "openbox/stacking.h" +#include "openbox/window.h" #include "openbox/event.h" #include "openbox/focus_cycle.h" #include "openbox/openbox.h" @@ -11,6 +13,8 @@ typedef struct { gboolean desktop_windows; gboolean all_desktops; gboolean forward; + gboolean bar; + gboolean raise; GSList *actions; } Options; @@ -46,11 +50,16 @@ static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node) o = g_new0(Options, 1); o->dialog = TRUE; + o->bar = TRUE; if ((n = parse_find_node("linear", node))) o->linear = parse_bool(doc, n); if ((n = parse_find_node("dialog", node))) o->dialog = parse_bool(doc, n); + if ((n = parse_find_node("bar", node))) + o->bar = parse_bool(doc, n); + if ((n = parse_find_node("raise", node))) + o->raise = parse_bool(doc, n); if ((n = parse_find_node("panels", node))) o->dock_windows = parse_bool(doc, n); if ((n = parse_find_node("desktop", node))) @@ -111,17 +120,22 @@ static void free_func(gpointer options) static gboolean run_func(ObActionsData *data, gpointer options) { Options *o = options; + struct _ObClient *ft; - focus_cycle(o->forward, - o->all_desktops, - o->dock_windows, - o->desktop_windows, - o->linear, - TRUE, - o->dialog, - FALSE, FALSE); + ft = focus_cycle(o->forward, + o->all_desktops, + o->dock_windows, + o->desktop_windows, + o->linear, + TRUE, + o->bar, + o->dialog, + FALSE, FALSE); cycling = TRUE; + stacking_restore(); + if (o->raise) stacking_temp_raise(CLIENT_AS_WINDOW(ft)); + return TRUE; } @@ -174,6 +188,7 @@ static void end_cycle(gboolean cancel, guint state, Options *o) o->desktop_windows, o->linear, TRUE, + o->bar, o->dialog, TRUE, cancel); cycling = FALSE; @@ -181,4 +196,6 @@ static void end_cycle(gboolean cancel, guint state, Options *o) if (ft) actions_run_acts(o->actions, OB_USER_ACTION_KEYBOARD_KEY, state, -1, -1, 0, OB_FRAME_CONTEXT_NONE, ft); + + stacking_restore(); } diff --git a/openbox/actions/directionalwindows.c b/openbox/actions/directionalwindows.c index 707659eb..c575d84e 100644 --- a/openbox/actions/directionalwindows.c +++ b/openbox/actions/directionalwindows.c @@ -1,5 +1,7 @@ #include "openbox/actions.h" #include "openbox/event.h" +#include "openbox/stacking.h" +#include "openbox/window.h" #include "openbox/focus_cycle.h" #include "openbox/openbox.h" #include "openbox/misc.h" @@ -11,6 +13,8 @@ typedef struct { gboolean dock_windows; gboolean desktop_windows; ObDirection direction; + gboolean bar; + gboolean raise; GSList *actions; } Options; @@ -46,9 +50,14 @@ static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node) o = g_new0(Options, 1); o->dialog = TRUE; + o->bar = TRUE; if ((n = parse_find_node("dialog", node))) o->dialog = parse_bool(doc, n); + if ((n = parse_find_node("bar", node))) + o->bar = parse_bool(doc, n); + if ((n = parse_find_node("raise", node))) + o->raise = parse_bool(doc, n); if ((n = parse_find_node("panels", node))) o->dock_windows = parse_bool(doc, n); if ((n = parse_find_node("desktop", node))) @@ -135,13 +144,19 @@ static gboolean run_func(ObActionsData *data, gpointer options) if (!o->interactive) end_cycle(FALSE, data->state, o); else { - focus_directional_cycle(o->direction, - o->dock_windows, - o->desktop_windows, - TRUE, - o->dialog, - FALSE, FALSE); + struct _ObClient *ft; + + ft = focus_directional_cycle(o->direction, + o->dock_windows, + o->desktop_windows, + TRUE, + o->bar, + o->dialog, + FALSE, FALSE); cycling = TRUE; + + stacking_restore(); + if (o->raise) stacking_temp_raise(CLIENT_AS_WINDOW(ft)); } return o->interactive; @@ -194,12 +209,14 @@ static void end_cycle(gboolean cancel, guint state, Options *o) o->dock_windows, o->desktop_windows, o->interactive, + o->bar, o->dialog, TRUE, cancel); cycling = FALSE; - if (ft) { + if (ft) actions_run_acts(o->actions, OB_USER_ACTION_KEYBOARD_KEY, state, -1, -1, 0, OB_FRAME_CONTEXT_NONE, ft); - } + + stacking_restore(); } diff --git a/openbox/focus_cycle.c b/openbox/focus_cycle.c index 85cdf480..2348f8d0 100644 --- a/openbox/focus_cycle.c +++ b/openbox/focus_cycle.c @@ -62,15 +62,16 @@ void focus_cycle_stop(ObClient *ifclient) focus_cycle_dock_windows, focus_cycle_desktop_windows)) { - focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); - focus_directional_cycle(0, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); + focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,TRUE); + focus_directional_cycle(0, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); } } ObClient* focus_cycle(gboolean forward, gboolean all_desktops, gboolean dock_windows, gboolean desktop_windows, gboolean linear, gboolean interactive, - gboolean dialog, gboolean done, gboolean cancel) + gboolean showbar, gboolean dialog, + gboolean done, gboolean cancel) { static ObClient *t = NULL; static GList *order = NULL; @@ -128,7 +129,7 @@ ObClient* focus_cycle(gboolean forward, gboolean all_desktops, if (interactive) { if (ft != focus_cycle_target) { /* prevents flicker */ focus_cycle_target = ft; - focus_cycle_draw_indicator(ft); + focus_cycle_draw_indicator(showbar ? ft : NULL); } if (dialog) /* same arguments as focus_target_valid */ @@ -261,7 +262,7 @@ static ObClient *focus_find_directional(ObClient *c, ObDirection dir, ObClient* focus_directional_cycle(ObDirection dir, gboolean dock_windows, gboolean desktop_windows, gboolean interactive, - gboolean dialog, + gboolean showbar, gboolean dialog, gboolean done, gboolean cancel) { static ObClient *first = NULL; @@ -307,7 +308,7 @@ ObClient* focus_directional_cycle(ObDirection dir, gboolean dock_windows, focus_cycle_target = ft; if (!interactive) goto done_cycle; - focus_cycle_draw_indicator(ft); + focus_cycle_draw_indicator(showbar ? ft : NULL); } if (focus_cycle_target && dialog) /* same arguments as focus_target_valid */ diff --git a/openbox/focus_cycle.h b/openbox/focus_cycle.h index 68b8d929..6e1c2c9d 100644 --- a/openbox/focus_cycle.h +++ b/openbox/focus_cycle.h @@ -37,11 +37,13 @@ void focus_cycle_shutdown(gboolean reconfig); struct _ObClient* focus_cycle(gboolean forward, gboolean all_desktops, gboolean dock_windows, gboolean desktop_windows, gboolean linear, gboolean interactive, - gboolean dialog, gboolean done, gboolean cancel); + gboolean showbar, gboolean dialog, + gboolean done, gboolean cancel); struct _ObClient* focus_directional_cycle(ObDirection dir, gboolean dock_windows, gboolean desktop_windows, gboolean interactive, + gboolean showbar, gboolean dialog, gboolean done, gboolean cancel); diff --git a/openbox/focus_cycle_indicator.c b/openbox/focus_cycle_indicator.c index 79071314..5a6a1029 100644 --- a/openbox/focus_cycle_indicator.c +++ b/openbox/focus_cycle_indicator.c @@ -39,6 +39,7 @@ struct static RrAppearance *a_focus_indicator; static RrColor *color_white; +static gboolean visible; static Window create_window(Window parent, gulong mask, XSetWindowAttributes *attrib) @@ -53,6 +54,8 @@ void focus_cycle_indicator_startup(gboolean reconfig) { XSetWindowAttributes attr; + visible = FALSE; + if (reconfig) return; focus_indicator.top.obwin.type = Window_Internal; @@ -118,7 +121,7 @@ void focus_cycle_indicator_shutdown(gboolean reconfig) void focus_cycle_draw_indicator(ObClient *c) { - if (!c) { + if (!c && visible) { gulong ignore_start; /* kill enter events cause by this unmapping */ @@ -130,7 +133,10 @@ void focus_cycle_draw_indicator(ObClient *c) XUnmapWindow(ob_display, focus_indicator.bottom.win); event_end_ignore_all_enters(ignore_start); - } else { + + visible = FALSE; + } + else if (c) { /* if (c) frame_adjust_focus(c->frame, FALSE); @@ -249,5 +255,7 @@ void focus_cycle_draw_indicator(ObClient *c) XMapWindow(ob_display, focus_indicator.left.win); XMapWindow(ob_display, focus_indicator.right.win); XMapWindow(ob_display, focus_indicator.bottom.win); + + visible = TRUE; } } -- cgit v1.2.3 From 22c102572e892dc36b1c411edbd70415efe1f0e6 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 16:26:16 -0500 Subject: fix a crash when reconfiguring during focus cycling --- openbox/focus_cycle_popup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'openbox') diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c index 488ecce1..028fa45d 100644 --- a/openbox/focus_cycle_popup.c +++ b/openbox/focus_cycle_popup.c @@ -146,6 +146,7 @@ void focus_cycle_popup_shutdown(gboolean reconfig) } g_free(popup.hilite_rgba); + popup.hilite_rgba = NULL; XDestroyWindow(ob_display, popup.text); XDestroyWindow(ob_display, popup.bg); -- cgit v1.2.3 From e61f58462fe0cdd85090b621c6906b2885990071 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 16:29:11 -0500 Subject: freeze onscreen stacking order changes while a temp raise for focus cycling is occuring --- openbox/stacking.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'openbox') diff --git a/openbox/stacking.c b/openbox/stacking.c index bb8975d4..34ab0588 100644 --- a/openbox/stacking.c +++ b/openbox/stacking.c @@ -28,6 +28,10 @@ #include "debug.h" GList *stacking_list = NULL; +/*! When true, stacking changes will not be reflected on the screen. This is + to freeze the on-screen stacking order while a window is being temporarily + raised during focus cycling */ +gboolean pause_changes = FALSE; void stacking_set_list(void) { @@ -99,7 +103,8 @@ static void do_restack(GList *wins, GList *before) } #endif - XRestackWindows(ob_display, win, i); + if (!pause_changes) + XRestackWindows(ob_display, win, i); g_free(win); stacking_set_list(); @@ -125,6 +130,8 @@ void stacking_temp_raise(ObWindow *window) win[1] = window_top(window); XRestackWindows(ob_display, win, 2); + + pause_changes = TRUE; } void stacking_restore() @@ -139,6 +146,8 @@ void stacking_restore() win[i] = window_top(it->data); XRestackWindows(ob_display, win, i); g_free(win); + + pause_changes = FALSE; } static void do_raise(GList *wins) -- cgit v1.2.3 From b3764dd433f8e8511bf3045e4ea5e0e5df6b2a70 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sat, 5 Jan 2008 12:40:46 +0100 Subject: Don't record desktops for lastdesktop when switching away quickly again. When switching desktops, only record the previous desktop as the last desktop if the user stayed there for a while. This way you can scroll over a couple desktops quickly, then go back to the previous desktop you _used_, not the last you scrolled past. --- openbox/screen.c | 50 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) (limited to 'openbox') diff --git a/openbox/screen.c b/openbox/screen.c index a8da15c0..e81b9590 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -59,7 +59,9 @@ static void screen_fallback_focus(void); guint screen_num_desktops; guint screen_num_monitors; guint screen_desktop; -guint screen_last_desktop; +guint screen_last_desktop = 1; +guint screen_old_desktop; +gboolean screen_desktop_timeout = TRUE; Size screen_physical_size; gboolean screen_showing_desktop; ObDesktopLayout screen_desktop_layout; @@ -577,23 +579,61 @@ static void screen_fallback_focus(void) } } +static gboolean last_desktop_func(gpointer data) +{ + screen_desktop_timeout = TRUE; + return FALSE; +} + void screen_set_desktop(guint num, gboolean dofocus) { GList *it; - guint old; + guint previous; gulong ignore_start; g_assert(num < screen_num_desktops); - old = screen_desktop; + previous = screen_desktop; screen_desktop = num; - if (old == num) return; + if (previous == num) return; PROP_SET32(RootWindow(ob_display, ob_screen), net_current_desktop, cardinal, num); - screen_last_desktop = old; + if (screen_desktop_timeout) { + if (screen_desktop == screen_last_desktop) { + screen_last_desktop = previous; + screen_old_desktop = screen_desktop; + } else { + screen_old_desktop = screen_last_desktop; + screen_last_desktop = previous; + } + } else { + if (screen_desktop == screen_last_desktop) { + if (previous == screen_old_desktop) { + screen_last_desktop = screen_old_desktop; + } else if (screen_last_desktop == screen_old_desktop) { + screen_last_desktop = previous; + } else { + screen_last_desktop = screen_old_desktop; + } + } else { + if (screen_desktop == screen_old_desktop) { + /* do nothing */ + } else if (previous == screen_old_desktop) { + /* do nothing */ + } else if (screen_last_desktop == screen_old_desktop) { + screen_last_desktop = previous; + } else { + /* do nothing */ + } + } + } + screen_desktop_timeout = FALSE; + ob_main_loop_timeout_remove(ob_main_loop, last_desktop_func); + ob_main_loop_timeout_add(ob_main_loop, 500000, last_desktop_func, + NULL, NULL, NULL); ob_debug("Moving to desktop %d\n", num+1); -- cgit v1.2.3 From 8a2adbb0585dfc150c4809327a2c41265174b533 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 16:49:55 -0500 Subject: make the time to remember last desktop a #define, and make it 750ms --- openbox/screen.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'openbox') diff --git a/openbox/screen.c b/openbox/screen.c index e81b9590..5e0f67d4 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -79,6 +79,10 @@ static GSList *struts_bottom = NULL; static ObPagerPopup *desktop_popup; +/*! The number of microseconds that you need to be on a desktop before it will + replace the remembered "last desktop" */ +#define REMEMBER_LAST_DESKTOP_TIME 750000 + static gboolean replace_wm(void) { gchar *wm_sn; @@ -632,8 +636,8 @@ void screen_set_desktop(guint num, gboolean dofocus) } screen_desktop_timeout = FALSE; ob_main_loop_timeout_remove(ob_main_loop, last_desktop_func); - ob_main_loop_timeout_add(ob_main_loop, 500000, last_desktop_func, - NULL, NULL, NULL); + ob_main_loop_timeout_add(ob_main_loop, REMEMBER_LAST_DESKTOP_TIME, + last_desktop_func, NULL, NULL, NULL); ob_debug("Moving to desktop %d\n", num+1); -- cgit v1.2.3 From 6133bbd5f732622d8d5650d262413429c38af842 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 17:24:13 -0500 Subject: try to comment the code for when to save the "last desktop" --- openbox/screen.c | 63 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 17 deletions(-) (limited to 'openbox') diff --git a/openbox/screen.c b/openbox/screen.c index 5e0f67d4..379a12d8 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -605,32 +605,61 @@ void screen_set_desktop(guint num, gboolean dofocus) PROP_SET32(RootWindow(ob_display, ob_screen), net_current_desktop, cardinal, num); + /* This whole thing decides when/how to save the screen_last_desktop so + that it can be restored later if you want */ if (screen_desktop_timeout) { + /* If screen_desktop_timeout is true, then we've been on this desktop + long enough and we can save it as the last desktop. */ + + /* save the "last desktop" as the "old desktop" */ + screen_old_desktop = screen_last_desktop; + /* save the desktop we're coming from as the "last desktop" */ + screen_last_desktop = previous; + } + else { + /* If screen_desktop_timeout is false, then we just got to this desktop + and we are moving away again. */ + if (screen_desktop == screen_last_desktop) { - screen_last_desktop = previous; - screen_old_desktop = screen_desktop; - } else { - screen_old_desktop = screen_last_desktop; - screen_last_desktop = previous; - } - } else { - if (screen_desktop == screen_last_desktop) { + /* If we are moving to the "last desktop" .. */ if (previous == screen_old_desktop) { + /* .. from the "old desktop", change the last desktop to + be where we are coming from */ screen_last_desktop = screen_old_desktop; - } else if (screen_last_desktop == screen_old_desktop) { + } + else if (screen_last_desktop == screen_old_desktop) { + /* .. and also to the "old desktop", change the "last + desktop" to be where we are coming from */ screen_last_desktop = previous; - } else { + } + else { + /* .. from some other desktop, then set the "last desktop" to + be the saved "old desktop", i.e. where we were before the + "last desktop" */ screen_last_desktop = screen_old_desktop; } - } else { + } + else { + /* If we are moving to any desktop besides the "last desktop".. + (this is the normal case) */ if (screen_desktop == screen_old_desktop) { - /* do nothing */ - } else if (previous == screen_old_desktop) { - /* do nothing */ - } else if (screen_last_desktop == screen_old_desktop) { + /* If moving to the "old desktop", which is not the + "last desktop", don't save anything */ + } + else if (previous == screen_old_desktop) { + /* If moving from the "old desktop", and not to the + "last desktop", don't save anything */ + } + else if (screen_last_desktop == screen_old_desktop) { + /* If the "last desktop" is the same as "old desktop" and + you're not moving to the "last desktop" then save where + we're coming from as the "last desktop" */ screen_last_desktop = previous; - } else { - /* do nothing */ + } + else { + /* If the "last desktop" is different from the "old desktop" + and you're not moving to the "last desktop", then don't save + anything */ } } } -- cgit v1.2.3 From 2b80e4e8ef56bb4fba614139601e750344418e5b Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 18:13:12 -0500 Subject: ignore mouse clicks on override-redirect windows that aren't owned by openbox --- openbox/event.c | 48 ++++++++++++++++++++++++++++++++++++++++----- openbox/focus_cycle_popup.c | 2 ++ openbox/popup.c | 2 ++ openbox/window.h | 3 ++- 4 files changed, 49 insertions(+), 6 deletions(-) (limited to 'openbox') diff --git a/openbox/event.c b/openbox/event.c index 03229117..cd562599 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -694,12 +694,50 @@ static void event_process(const XEvent *ec, gpointer data) } #endif - if (e->type == ButtonPress || e->type == ButtonRelease || - e->type == MotionNotify || e->type == KeyPress || - e->type == KeyRelease) - { - event_handle_user_input(client, e); + if (e->type == ButtonPress || e->type == ButtonRelease) { + /* If the button press was on some non-root window, or was physically + on the root window, the process it */ + if (window != RootWindow(ob_display, ob_screen) || + e->xbutton.subwindow == None) + { + event_handle_user_input(client, e); + } + /* Otherwise only process it if it was physically on an openbox + internal window */ + else { + Window target, parent, root, *children; + unsigned int nchildren; + ObWindow *w; + + /* Find the top level ancestor of the subwindow, besides the + root */ + target = e->xbutton.subwindow; + ob_debug("subwindow 0x%x\n", target); + while (XQueryTree(ob_display, target, &root, &parent, &children, + &nchildren) != 0) + { + XFree(children); + if (parent == root) { + ob_debug("parent is root\n"); + break; + } + target = parent; + } + ob_debug("toplevel 0x%x\n", target); + + w = g_hash_table_lookup(window_map, &target); + ob_debug("w 0x%x\n", w); + + if ((w = g_hash_table_lookup(window_map, &target)) && + WINDOW_IS_INTERNAL(w)) + { + event_handle_user_input(client, e); + } + } } + else if (e->type == KeyPress || e->type == KeyRelease || + e->type == MotionNotify) + event_handle_user_input(client, e); /* if something happens and it's not from an XEvent, then we don't know the time */ diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c index 028fa45d..9a6f2420 100644 --- a/openbox/focus_cycle_popup.c +++ b/openbox/focus_cycle_popup.c @@ -128,12 +128,14 @@ void focus_cycle_popup_startup(gboolean reconfig) XMapWindow(ob_display, popup.text); stacking_add(INTERNAL_AS_WINDOW(&popup)); + g_hash_table_insert(window_map, &popup.bg, &popup); } void focus_cycle_popup_shutdown(gboolean reconfig) { icon_popup_free(single_popup); + g_hash_table_remove(window_map, &popup.bg); stacking_remove(INTERNAL_AS_WINDOW(&popup)); while(popup.targets) { diff --git a/openbox/popup.c b/openbox/popup.c index 071f5b62..283348e7 100644 --- a/openbox/popup.c +++ b/openbox/popup.c @@ -58,6 +58,7 @@ ObPopup *popup_new(void) XMapWindow(ob_display, self->text); stacking_add(INTERNAL_AS_WINDOW(self)); + g_hash_table_insert(window_map, &self->bg, self); return self; } @@ -68,6 +69,7 @@ void popup_free(ObPopup *self) XDestroyWindow(ob_display, self->text); RrAppearanceFree(self->a_bg); RrAppearanceFree(self->a_text); + g_hash_table_remove(window_map, &self->bg); stacking_remove(self); g_free(self); } diff --git a/openbox/window.h b/openbox/window.h index aaf83995..a172cfce 100644 --- a/openbox/window.h +++ b/openbox/window.h @@ -32,7 +32,8 @@ typedef enum { Window_Dock, Window_DockApp, /* used for events but not stacking */ Window_Client, - Window_Internal /* used for stacking but not events */ + Window_Internal /* used for stacking but not events (except to filter + events on the root window) */ } Window_InternalType; struct _ObWindow -- cgit v1.2.3 From bf259be653b9c37c79f9cd8ababffe225857ce9f Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 18:28:35 -0500 Subject: fixes from commit 0ce14a727968736e57fb3fabba3794b46903875f the xsync was needed to get the right serial for the end of the ignore range --- openbox/event.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'openbox') diff --git a/openbox/event.c b/openbox/event.c index cd562599..cc3ea68f 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -74,6 +74,7 @@ typedef struct { ObClient *client; Time time; + gulong serial; } ObFocusDelayData; typedef struct @@ -246,7 +247,6 @@ static void event_set_curtime(XEvent *e) event_last_user_time = CurrentTime; event_curtime = t; - event_curserial = 0; } static void event_hack_mods(XEvent *e) @@ -742,6 +742,7 @@ static void event_process(const XEvent *ec, gpointer data) /* if something happens and it's not from an XEvent, then we don't know the time */ event_curtime = CurrentTime; + event_curserial = 0; } static void event_handle_root(XEvent *e) @@ -816,6 +817,7 @@ void event_enter_client(ObClient *client) data = g_new(ObFocusDelayData, 1); data->client = client; data->time = event_curtime; + data->serial = event_curserial; ob_main_loop_timeout_add(ob_main_loop, config_focus_delay * 1000, @@ -825,6 +827,7 @@ void event_enter_client(ObClient *client) ObFocusDelayData data; data.client = client; data.time = event_curtime; + data.serial = event_curserial; focus_delay_func(&data); } } @@ -1912,6 +1915,7 @@ static gboolean focus_delay_func(gpointer data) if (menu_frame_visible || moveresize_in_progress) return FALSE; event_curtime = d->time; + event_curserial = d->serial; if (client_focus(d->client) && config_focus_raise) stacking_raise(CLIENT_AS_WINDOW(d->client)); event_curtime = old; @@ -1924,7 +1928,7 @@ static void focus_delay_client_dest(ObClient *client, gpointer data) client, FALSE); } -void event_halt_focus_delay(gulong serial) +void event_halt_focus_delay() { /* ignore all enter events up till the event which caused this to occur */ if (event_curserial) event_ignore_enter_range(1, event_curserial); @@ -1933,7 +1937,6 @@ void event_halt_focus_delay(gulong serial) gulong event_start_ignore_all_enters(void) { - /* increment the serial so we don't ignore events we weren't meant to */ XSync(ob_display, FALSE); return LastKnownRequestProcessed(ob_display); } @@ -1959,6 +1962,7 @@ static void event_ignore_enter_range(gulong start, gulong end) void event_end_ignore_all_enters(gulong start) { + XSync(ob_display, FALSE); event_ignore_enter_range(start, LastKnownRequestProcessed(ob_display)); } -- cgit v1.2.3 From 78cd9bba523f4986413e3aefe87704e9d11cd081 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 18:33:43 -0500 Subject: continue commit 2b80e4e8ef56bb4fba614139601e750344418e5b - remove debug code, and some unneeded stuff --- openbox/event.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) (limited to 'openbox') diff --git a/openbox/event.c b/openbox/event.c index cc3ea68f..d2cb7567 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -705,30 +705,9 @@ static void event_process(const XEvent *ec, gpointer data) /* Otherwise only process it if it was physically on an openbox internal window */ else { - Window target, parent, root, *children; - unsigned int nchildren; ObWindow *w; - /* Find the top level ancestor of the subwindow, besides the - root */ - target = e->xbutton.subwindow; - ob_debug("subwindow 0x%x\n", target); - while (XQueryTree(ob_display, target, &root, &parent, &children, - &nchildren) != 0) - { - XFree(children); - if (parent == root) { - ob_debug("parent is root\n"); - break; - } - target = parent; - } - ob_debug("toplevel 0x%x\n", target); - - w = g_hash_table_lookup(window_map, &target); - ob_debug("w 0x%x\n", w); - - if ((w = g_hash_table_lookup(window_map, &target)) && + if ((w = g_hash_table_lookup(window_map, &e->xbutton.subwindow)) && WINDOW_IS_INTERNAL(w)) { event_handle_user_input(client, e); -- cgit v1.2.3 From 040d344a89f40487de8a1920e0aaeccd93a6a995 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 18:57:32 -0500 Subject: don't take KeyRelease events for menus until they receive a KeyPress event first. avoid using the key binding used to show the menu to execute something inside it. --- openbox/event.c | 4 +++- openbox/menuframe.h | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'openbox') diff --git a/openbox/event.c b/openbox/event.c index d2cb7567..6b0ecdd7 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -1671,6 +1671,8 @@ static gboolean event_handle_menu_keyboard(XEvent *ev) /* 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)) { menu_frame_hide_all(); ret = TRUE; @@ -1704,7 +1706,7 @@ static gboolean event_handle_menu_keyboard(XEvent *ev) Allow ControlMask only, and don't bother if the menu is empty */ else if (ev->type == KeyRelease && (state & ~ControlMask) == 0 && - frame->entries) + frame->entries && frame->got_press) { if (keycode == ob_keycode(OB_KEY_RETURN)) { /* Enter runs the active item or goes into the submenu. diff --git a/openbox/menuframe.h b/openbox/menuframe.h index 191bcfe8..06975972 100644 --- a/openbox/menuframe.h +++ b/openbox/menuframe.h @@ -73,6 +73,11 @@ struct _ObMenuFrame RrAppearance *a_title; RrAppearance *a_items; + + gboolean got_press; /* don't allow a KeyRelease event to run things in the + menu until it has seen a KeyPress. this is to + avoid having the keybinding used to show the menu + end up running something inside the menu */ }; struct _ObMenuEntryFrame -- cgit v1.2.3 From d7b25da169d0a466e3fd88bec9344e25d64584f6 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 19:05:04 -0500 Subject: make the window_startup happen before the focus_cycle_popup startup, so that the popups can be added to the window map properly --- openbox/openbox.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'openbox') diff --git a/openbox/openbox.c b/openbox/openbox.c index ff226af4..c7e28324 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -292,12 +292,12 @@ gint main(gint argc, gchar **argv) event_startup(reconfigure); /* focus_backup is used for stacking, so this needs to come before anything that calls stacking_add */ + sn_startup(reconfigure); + window_startup(reconfigure); focus_startup(reconfigure); focus_cycle_startup(reconfigure); focus_cycle_indicator_startup(reconfigure); focus_cycle_popup_startup(reconfigure); - window_startup(reconfigure); - sn_startup(reconfigure); screen_startup(reconfigure); grab_startup(reconfigure); group_startup(reconfigure); @@ -367,8 +367,8 @@ gint main(gint argc, gchar **argv) focus_cycle_indicator_shutdown(reconfigure); focus_cycle_shutdown(reconfigure); focus_shutdown(reconfigure); - sn_shutdown(reconfigure); window_shutdown(reconfigure); + sn_shutdown(reconfigure); event_shutdown(reconfigure); config_shutdown(); actions_shutdown(reconfigure); -- cgit v1.2.3 From 602a73c15ce22250a604e443a994ad6c8726f3f5 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 19:30:29 -0500 Subject: make fake xinerama happen even when xinerama is enabled --- openbox/extensions.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'openbox') diff --git a/openbox/extensions.c b/openbox/extensions.c index ee73e9ec..d1088361 100644 --- a/openbox/extensions.c +++ b/openbox/extensions.c @@ -86,6 +86,16 @@ void extensions_xinerama_screens(Rect **xin_areas, guint *nxin) { guint i; gint l, r, t, b; + if (ob_debug_xinerama) { + g_print("Using fake xinerama !\n"); + gint w = WidthOfScreen(ScreenOfDisplay(ob_display, ob_screen)); + gint h = HeightOfScreen(ScreenOfDisplay(ob_display, ob_screen)); + *nxin = 2; + *xin_areas = g_new(Rect, *nxin + 1); + RECT_SET((*xin_areas)[0], 0, 0, w/2, h); + RECT_SET((*xin_areas)[1], w/2, 0, w-(w/2), h); + } + else #ifdef XINERAMA if (extensions_xinerama) { guint i; @@ -97,17 +107,10 @@ void extensions_xinerama_screens(Rect **xin_areas, guint *nxin) RECT_SET((*xin_areas)[i], info[i].x_org, info[i].y_org, info[i].width, info[i].height); XFree(info); - } else -#endif - if (ob_debug_xinerama) { - gint w = WidthOfScreen(ScreenOfDisplay(ob_display, ob_screen)); - gint h = HeightOfScreen(ScreenOfDisplay(ob_display, ob_screen)); - *nxin = 2; - *xin_areas = g_new(Rect, *nxin + 1); - RECT_SET((*xin_areas)[0], 0, 0, w/2, h); - RECT_SET((*xin_areas)[1], w/2, 0, w-(w/2), h); } - else { + else +#endif + { *nxin = 1; *xin_areas = g_new(Rect, *nxin + 1); RECT_SET((*xin_areas)[0], 0, 0, -- cgit v1.2.3 From 22333336d3ba36784955c67444f996b557f3838a Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 19:32:45 -0500 Subject: add an option for window placement, to try force new windows on the active monitor (for xinerama) --- openbox/config.c | 4 ++++ openbox/config.h | 4 ++++ openbox/place.c | 13 ++++++++----- 3 files changed, 16 insertions(+), 5 deletions(-) (limited to 'openbox') diff --git a/openbox/config.c b/openbox/config.c index ff4c542b..25e30fff 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -38,6 +38,7 @@ gboolean config_focus_under_mouse; ObPlacePolicy config_place_policy; gboolean config_place_center; +gboolean config_place_active; StrutPartial config_margins; @@ -500,6 +501,8 @@ static void parse_placement(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, config_place_policy = OB_PLACE_POLICY_MOUSE; if ((n = parse_find_node("center", node))) config_place_center = parse_bool(doc, n); + if ((n = parse_find_node("active", node))) + config_place_active = parse_bool(doc, n); } static void parse_margins(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, @@ -880,6 +883,7 @@ void config_startup(ObParseInst *i) config_place_policy = OB_PLACE_POLICY_SMART; config_place_center = TRUE; + config_place_active = FALSE; parse_register(i, "placement", parse_placement, NULL); diff --git a/openbox/config.h b/openbox/config.h index 9d0602e2..2c4b4dba 100644 --- a/openbox/config.h +++ b/openbox/config.h @@ -75,9 +75,13 @@ extern gboolean config_focus_last; */ extern gboolean config_focus_under_mouse; +/*! The algorithm to use for placing new windows */ extern ObPlacePolicy config_place_policy; /*! Place windows in the center of the free area */ extern gboolean config_place_center; +/*! Place windows on the active monitor (unless they are part of an application + already on another monitor) */ +extern gboolean config_place_active; /*! User-specified margins around the edge of the screen(s) */ extern StrutPartial config_margins; diff --git a/openbox/place.c b/openbox/place.c index aa572db2..276d9288 100644 --- a/openbox/place.c +++ b/openbox/place.c @@ -108,9 +108,9 @@ static Rect **pick_head(ObClient *c) } } - if (focus_client) { + if (focus_client && client_normal(focus_client)) { add_choice(choice, client_monitor(focus_client)); - ob_debug("placement adding choice %d for focused window\n", + ob_debug("placement adding choice %d for normal focused window\n", client_monitor(focus_client)); } @@ -146,7 +146,7 @@ static gboolean place_random(ObClient *client, gint *x, gint *y) guint i; areas = pick_head(client); - i = g_random_int_range(0, screen_num_monitors); + i = config_place_active ? 0 : g_random_int_range(0, screen_num_monitors); l = areas[i]->x; t = areas[i]->y; @@ -254,8 +254,11 @@ static gboolean place_nooverlap(ObClient *c, gint *x, gint *y) /* try ignoring different things to find empty space */ for (ignore = 0; ignore < IGNORE_END && !ret; ignore++) { - /* try all monitors in order of preference */ - for (i = 0; i < screen_num_monitors && !ret; ++i) { + /* try all monitors in order of preference, but only the first one + if config_place_active is true */ + for (i = 0; (i < (config_place_active ? 1 : screen_num_monitors) && + !ret); ++i) + { GList *it; /* add the whole monitor */ -- cgit v1.2.3 From b7e23f286a53b7beb259afac7e1a4cdf5fca47a4 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 19:45:30 -0500 Subject: make the focus cycle indicator be in the window_map so button presses on it are handled right --- openbox/focus_cycle_indicator.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'openbox') diff --git a/openbox/focus_cycle_indicator.c b/openbox/focus_cycle_indicator.c index 5a6a1029..340abec6 100644 --- a/openbox/focus_cycle_indicator.c +++ b/openbox/focus_cycle_indicator.c @@ -82,6 +82,14 @@ void focus_cycle_indicator_startup(gboolean reconfig) stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.left)); stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.right)); stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.bottom)); + g_hash_table_insert(window_map, &focus_indicator.top.win, + &focus_indicator.top); + g_hash_table_insert(window_map, &focus_indicator.left.win, + &focus_indicator.left); + g_hash_table_insert(window_map, &focus_indicator.right.win, + &focus_indicator.right); + g_hash_table_insert(window_map, &focus_indicator.bottom.win, + &focus_indicator.bottom); color_white = RrColorNew(ob_rr_inst, 0xff, 0xff, 0xff); @@ -108,6 +116,11 @@ void focus_cycle_indicator_shutdown(gboolean reconfig) RrAppearanceFree(a_focus_indicator); + g_hash_table_remove(window_map, &focus_indicator.top.win); + g_hash_table_remove(window_map, &focus_indicator.left.win); + g_hash_table_remove(window_map, &focus_indicator.right.win); + g_hash_table_remove(window_map, &focus_indicator.bottom.win); + stacking_remove(INTERNAL_AS_WINDOW(&focus_indicator.top)); stacking_remove(INTERNAL_AS_WINDOW(&focus_indicator.left)); stacking_remove(INTERNAL_AS_WINDOW(&focus_indicator.right)); -- cgit v1.2.3 From 17bc51aab8be25cd44c55eb0a652c92518bd9b0f Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 20:24:16 -0500 Subject: let you specify the resize popup to be in a fixed place --- openbox/config.c | 63 +++++++++++++++++++++++++++++++++++++++++++++------- openbox/config.h | 21 ++++++++++++++++-- openbox/moveresize.c | 47 +++++++++++++++++++++++++++++++++++++-- openbox/moveresize.h | 6 +++++ 4 files changed, 125 insertions(+), 12 deletions(-) (limited to 'openbox') diff --git a/openbox/config.c b/openbox/config.c index 25e30fff..05853666 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -60,10 +60,16 @@ GSList *config_desktops_names; guint config_screen_firstdesk; guint config_desktop_popup_time; -gboolean config_resize_redraw; -gboolean config_resize_four_corners; -gint config_resize_popup_show; -gint config_resize_popup_pos; +gboolean config_resize_redraw; +gboolean config_resize_four_corners; +gint config_resize_popup_show; +ObResizePopupPos config_resize_popup_pos; +gboolean config_resize_popup_x_center; +gboolean config_resize_popup_y_center; +gboolean config_resize_popup_x_opposite; +gboolean config_resize_popup_y_opposite; +gint config_resize_popup_x; +gint config_resize_popup_y; ObStackingLayer config_dock_layer; gboolean config_dock_floating; @@ -661,11 +667,46 @@ static void parse_resize(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, config_resize_popup_show = 1; } if ((n = parse_find_node("popupPosition", node))) { - config_resize_popup_pos = parse_int(doc, n); if (parse_contains("Top", doc, n)) - config_resize_popup_pos = 1; + config_resize_popup_pos = OB_RESIZE_POS_TOP; else if (parse_contains("Center", doc, n)) - config_resize_popup_pos = 0; + config_resize_popup_pos = OB_RESIZE_POS_CENTER; + else if (parse_contains("Fixed", doc, n)) { + config_resize_popup_pos = OB_RESIZE_POS_FIXED; + + if ((n = parse_find_node("popupFixedPosition", node))) { + xmlNodePtr n2; + + if ((n2 = parse_find_node("x", n->children))) { + gchar *s = parse_string(doc, n2); + if (!g_ascii_strcasecmp(s, "center")) + config_resize_popup_x_center = TRUE; + else { + if (s[0] == '-') + config_resize_popup_x_opposite = TRUE; + if (s[0] == '-' || s[0] == '+') + config_resize_popup_x = atoi(s+1); + else + config_resize_popup_x = atoi(s); + } + } + if ((n2 = parse_find_node("y", n->children))) { + gchar *s = parse_string(doc, n2); + if (!g_ascii_strcasecmp(s, "center")) + config_resize_popup_y_center = TRUE; + else { + if (s[0] == '-') + config_resize_popup_y_opposite = TRUE; + if (s[0] == '-' || s[0] == '+') + config_resize_popup_y = atoi(s+1); + else + config_resize_popup_y = atoi(s); + } + } + g_print("X %d %d %d\n", config_resize_popup_x_center, config_resize_popup_x_opposite, config_resize_popup_x); + g_print("Y %d %d %d\n", config_resize_popup_y_center, config_resize_popup_y_opposite, config_resize_popup_y); + } + } } } @@ -914,7 +955,13 @@ void config_startup(ObParseInst *i) config_resize_redraw = TRUE; config_resize_four_corners = FALSE; config_resize_popup_show = 1; /* nonpixel increments */ - config_resize_popup_pos = 0; /* center of client */ + config_resize_popup_pos = OB_RESIZE_POS_CENTER; + config_resize_popup_x_center = FALSE; + config_resize_popup_x_opposite = FALSE; + config_resize_popup_x = 0; + config_resize_popup_y_center = FALSE; + config_resize_popup_y_opposite = FALSE; + config_resize_popup_y = 0; parse_register(i, "resize", parse_resize, NULL); diff --git a/openbox/config.h b/openbox/config.h index 2c4b4dba..4fa9c70b 100644 --- a/openbox/config.h +++ b/openbox/config.h @@ -24,6 +24,7 @@ #include "stacking.h" #include "place.h" #include "geom.h" +#include "moveresize.h" #include "render/render.h" #include @@ -92,8 +93,24 @@ extern gboolean config_resize_redraw; /*! show move/resize popups? 0 = no, 1 = always, 2 = only resizing !1 increments */ extern gint config_resize_popup_show; -/*! where to show the popup, currently above the window or centered */ -extern gint config_resize_popup_pos; +/*! where to show the resize popup */ +extern ObResizePopupPos config_resize_popup_pos; +/*! if the resize popup should be centered horizontally if it is being + placed in a fixed position */ +extern gboolean config_resize_popup_x_center; +/*! if the resize popup should be centered vertically if it is being + placed in a fixed position */ +extern gboolean config_resize_popup_y_center; +/*! if the resize popup should be placed from the right side of the screen when + placed in a fixed position */ +extern gboolean config_resize_popup_x_opposite; +/*! if the resize popup should be placed from the bottom side of the screen + when placed in a fixed position */ +extern gboolean config_resize_popup_y_opposite; +/*! where the resize popup should be if it is placed in a fixed position */ +extern gint config_resize_popup_x; +/*! where the resize popup should be if it is placed in a fixed position */ +extern gint config_resize_popup_y; /*! The stacking layer the dock will reside in */ extern ObStackingLayer config_dock_layer; diff --git a/openbox/moveresize.c b/openbox/moveresize.c index bb17d4a0..07b8e22b 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -101,17 +101,60 @@ static void popup_coords(ObClient *c, const gchar *format, gint a, gint b) gchar *text; text = g_strdup_printf(format, a, b); - if (config_resize_popup_pos == 1) /* == "Top" */ + if (config_resize_popup_pos == OB_RESIZE_POS_TOP) popup_position(popup, SouthGravity, c->frame->area.x + c->frame->area.width/2, c->frame->area.y - ob_rr_theme->fbwidth); - else /* == "Center" */ + else if (config_resize_popup_pos == OB_RESIZE_POS_CENTER) popup_position(popup, CenterGravity, c->frame->area.x + c->frame->size.left + c->area.width / 2, c->frame->area.y + c->frame->size.top + c->area.height / 2); + else /* Fixed */ { + Rect *area = screen_physical_area_active(); + gint gravity, x, y; + + x = config_resize_popup_x; + if (config_resize_popup_x_center) x = area->x + area->width/2; + else if (config_resize_popup_x_opposite) x = RECT_RIGHT(*area) - x; + else x = area->x + x; + + y = config_resize_popup_y; + if (config_resize_popup_y_center) y = area->y + area->height/2; + else if (config_resize_popup_y_opposite) y = RECT_BOTTOM(*area) - y; + else y = area->y + y; + + if (config_resize_popup_x_center) { + if (config_resize_popup_y_center) + gravity = CenterGravity; + else if (config_resize_popup_y_opposite) + gravity = SouthGravity; + else + gravity = NorthGravity; + } + else if (config_resize_popup_x_opposite) { + if (config_resize_popup_y_center) + gravity = EastGravity; + else if (config_resize_popup_y_opposite) + gravity = SouthEastGravity; + else + gravity = NorthEastGravity; + } + else { + if (config_resize_popup_y_center) + gravity = WestGravity; + else if (config_resize_popup_y_opposite) + gravity = SouthWestGravity; + else + gravity = NorthWestGravity; + } + + popup_position(popup, gravity, x, y); + + g_free(area); + } popup_show(popup, text); g_free(text); } diff --git a/openbox/moveresize.h b/openbox/moveresize.h index 2f8d3e6a..2d0f7dce 100644 --- a/openbox/moveresize.h +++ b/openbox/moveresize.h @@ -27,6 +27,12 @@ struct _ObClient; +typedef enum { + OB_RESIZE_POS_CENTER, + OB_RESIZE_POS_TOP, + OB_RESIZE_POS_FIXED +} ObResizePopupPos; + extern gboolean moveresize_in_progress; extern struct _ObClient *moveresize_client; #ifdef SYNC -- cgit v1.2.3 From c2e495c720d93521bdb0e1bfd7e76584a1b329b7 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 20:58:03 -0500 Subject: make a GravityPoint and GravityCoord data structures for those --x, ++y type values --- openbox/config.c | 107 ++++++++++++++++----------------------------------- openbox/config.h | 24 ++---------- openbox/geom.h | 17 ++++++++ openbox/moveresize.c | 42 +++++++++++--------- openbox/place.c | 16 ++++---- 5 files changed, 85 insertions(+), 121 deletions(-) (limited to 'openbox') diff --git a/openbox/config.c b/openbox/config.c index 05853666..7ec2b3e0 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -64,12 +64,7 @@ gboolean config_resize_redraw; gboolean config_resize_four_corners; gint config_resize_popup_show; ObResizePopupPos config_resize_popup_pos; -gboolean config_resize_popup_x_center; -gboolean config_resize_popup_y_center; -gboolean config_resize_popup_x_opposite; -gboolean config_resize_popup_y_opposite; -gint config_resize_popup_x; -gint config_resize_popup_y; +GravityPoint config_resize_popup_fixed; ObStackingLayer config_dock_layer; gboolean config_dock_floating; @@ -143,16 +138,28 @@ void config_app_settings_copy_non_defaults(const ObAppSettings *src, if (src->pos_given) { dst->pos_given = TRUE; - dst->center_x = src->center_x; - dst->center_y = src->center_y; - dst->opposite_x = src->opposite_x; - dst->opposite_y = src->opposite_y; - dst->position.x = src->position.x; - dst->position.y = src->position.y; + dst->position = src->position; dst->monitor = src->monitor; } } +static void config_parse_gravity_coord(xmlDocPtr doc, xmlNodePtr node, + GravityCoord *c) +{ + gchar *s = parse_string(doc, node); + if (!g_ascii_strcasecmp(s, "center")) + c->center = TRUE; + else { + if (s[0] == '-') + c->opposite = TRUE; + if (s[0] == '-' || s[0] == '+') + c->pos = atoi(s+1); + else + c->pos = atoi(s); + } + g_free(s); +} + /* @@ -218,38 +225,16 @@ static void parse_per_app_settings(ObParseInst *inst, xmlDocPtr doc, if ((n = parse_find_node("position", app->children))) { if ((c = parse_find_node("x", n->children))) if (!parse_contains("default", doc, c)) { - gchar *s = parse_string(doc, c); - if (!g_ascii_strcasecmp(s, "center")) { - settings->center_x = TRUE; - x_pos_given = TRUE; - } else { - if (s[0] == '-') - settings->opposite_x = TRUE; - if (s[0] == '-' || s[0] == '+') - settings->position.x = atoi(s+1); - else - settings->position.x = atoi(s); - x_pos_given = TRUE; - } - g_free(s); + config_parse_gravity_coord(doc, c, + &settings->position.x); + settings->pos_given = TRUE; } if (x_pos_given && (c = parse_find_node("y", n->children))) if (!parse_contains("default", doc, c)) { - gchar *s = parse_string(doc, c); - if (!g_ascii_strcasecmp(s, "center")) { - settings->center_y = TRUE; - settings->pos_given = TRUE; - } else { - if (s[0] == '-') - settings->opposite_y = TRUE; - if (s[0] == '-' || s[0] == '+') - settings->position.y = atoi(s+1); - else - settings->position.y = atoi(s); - settings->pos_given = TRUE; - } - g_free(s); + config_parse_gravity_coord(doc, c, + &settings->position.y); + settings->pos_given = TRUE; } if (settings->pos_given && @@ -677,34 +662,12 @@ static void parse_resize(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, if ((n = parse_find_node("popupFixedPosition", node))) { xmlNodePtr n2; - if ((n2 = parse_find_node("x", n->children))) { - gchar *s = parse_string(doc, n2); - if (!g_ascii_strcasecmp(s, "center")) - config_resize_popup_x_center = TRUE; - else { - if (s[0] == '-') - config_resize_popup_x_opposite = TRUE; - if (s[0] == '-' || s[0] == '+') - config_resize_popup_x = atoi(s+1); - else - config_resize_popup_x = atoi(s); - } - } - if ((n2 = parse_find_node("y", n->children))) { - gchar *s = parse_string(doc, n2); - if (!g_ascii_strcasecmp(s, "center")) - config_resize_popup_y_center = TRUE; - else { - if (s[0] == '-') - config_resize_popup_y_opposite = TRUE; - if (s[0] == '-' || s[0] == '+') - config_resize_popup_y = atoi(s+1); - else - config_resize_popup_y = atoi(s); - } - } - g_print("X %d %d %d\n", config_resize_popup_x_center, config_resize_popup_x_opposite, config_resize_popup_x); - g_print("Y %d %d %d\n", config_resize_popup_y_center, config_resize_popup_y_opposite, config_resize_popup_y); + if ((n2 = parse_find_node("x", n->children))) + config_parse_gravity_coord(doc, n2, + &config_resize_popup_fixed.x); + if ((n2 = parse_find_node("y", n->children))) + config_parse_gravity_coord(doc, n2, + &config_resize_popup_fixed.y); } } } @@ -956,12 +919,8 @@ void config_startup(ObParseInst *i) config_resize_four_corners = FALSE; config_resize_popup_show = 1; /* nonpixel increments */ config_resize_popup_pos = OB_RESIZE_POS_CENTER; - config_resize_popup_x_center = FALSE; - config_resize_popup_x_opposite = FALSE; - config_resize_popup_x = 0; - config_resize_popup_y_center = FALSE; - config_resize_popup_y_opposite = FALSE; - config_resize_popup_y = 0; + GRAVITY_COORD_SET(config_resize_popup_fixed.x, 0, FALSE, FALSE); + GRAVITY_COORD_SET(config_resize_popup_fixed.y, 0, FALSE, FALSE); parse_register(i, "resize", parse_resize, NULL); diff --git a/openbox/config.h b/openbox/config.h index 4fa9c70b..240b04f1 100644 --- a/openbox/config.h +++ b/openbox/config.h @@ -39,11 +39,7 @@ struct _ObAppSettings GPatternSpec *name; GPatternSpec *role; - Point position; - gboolean center_x; - gboolean center_y; - gboolean opposite_x; - gboolean opposite_y; + GravityPoint position; gboolean pos_given; guint desktop; @@ -95,22 +91,8 @@ extern gboolean config_resize_redraw; extern gint config_resize_popup_show; /*! where to show the resize popup */ extern ObResizePopupPos config_resize_popup_pos; -/*! if the resize popup should be centered horizontally if it is being - placed in a fixed position */ -extern gboolean config_resize_popup_x_center; -/*! if the resize popup should be centered vertically if it is being - placed in a fixed position */ -extern gboolean config_resize_popup_y_center; -/*! if the resize popup should be placed from the right side of the screen when - placed in a fixed position */ -extern gboolean config_resize_popup_x_opposite; -/*! if the resize popup should be placed from the bottom side of the screen - when placed in a fixed position */ -extern gboolean config_resize_popup_y_opposite; -/*! where the resize popup should be if it is placed in a fixed position */ -extern gint config_resize_popup_x; -/*! where the resize popup should be if it is placed in a fixed position */ -extern gint config_resize_popup_y; +/*! where to place the popup if it's in a fixed position */ +extern GravityPoint config_resize_popup_fixed; /*! The stacking layer the dock will reside in */ extern ObStackingLayer config_dock_layer; diff --git a/openbox/geom.h b/openbox/geom.h index 43eb8ea3..bdcd3c55 100644 --- a/openbox/geom.h +++ b/openbox/geom.h @@ -20,6 +20,23 @@ #ifndef __geom_h #define __geom_h +#include + +typedef struct _GravityCoord { + int pos; + gboolean center; + gboolean opposite; +} GravityCoord; + +typedef struct _GravityPoint { + GravityCoord x; + GravityCoord y; +} GravityPoint; + +#define GRAVITY_COORD_SET(c, p, cen, opp) \ + (c).pos = (p), (c).center = (cen), (c).opposite = (opp) + + typedef struct _Point { int x; int y; diff --git a/openbox/moveresize.c b/openbox/moveresize.c index 07b8e22b..8dc122c7 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -116,36 +116,42 @@ static void popup_coords(ObClient *c, const gchar *format, gint a, gint b) Rect *area = screen_physical_area_active(); gint gravity, x, y; - x = config_resize_popup_x; - if (config_resize_popup_x_center) x = area->x + area->width/2; - else if (config_resize_popup_x_opposite) x = RECT_RIGHT(*area) - x; - else x = area->x + x; - - y = config_resize_popup_y; - if (config_resize_popup_y_center) y = area->y + area->height/2; - else if (config_resize_popup_y_opposite) y = RECT_BOTTOM(*area) - y; - else y = area->y + y; - - if (config_resize_popup_x_center) { - if (config_resize_popup_y_center) + x = config_resize_popup_fixed.x.pos; + if (config_resize_popup_fixed.x.center) + x = area->x + area->width/2; + else if (config_resize_popup_fixed.x.opposite) + x = RECT_RIGHT(*area) - x; + else + x = area->x + x; + + y = config_resize_popup_fixed.y.pos; + if (config_resize_popup_fixed.y.center) + y = area->y + area->width/2; + else if (config_resize_popup_fixed.y.opposite) + y = RECT_RIGHT(*area) - y; + else + y = area->y + y; + + if (config_resize_popup_fixed.x.center) { + if (config_resize_popup_fixed.y.center) gravity = CenterGravity; - else if (config_resize_popup_y_opposite) + else if (config_resize_popup_fixed.y.opposite) gravity = SouthGravity; else gravity = NorthGravity; } - else if (config_resize_popup_x_opposite) { - if (config_resize_popup_y_center) + else if (config_resize_popup_fixed.x.opposite) { + if (config_resize_popup_fixed.y.center) gravity = EastGravity; - else if (config_resize_popup_y_opposite) + else if (config_resize_popup_fixed.y.opposite) gravity = SouthEastGravity; else gravity = NorthEastGravity; } else { - if (config_resize_popup_y_center) + if (config_resize_popup_fixed.y.center) gravity = WestGravity; - else if (config_resize_popup_y_opposite) + else if (config_resize_popup_fixed.y.opposite) gravity = SouthWestGravity; else gravity = NorthWestGravity; diff --git a/openbox/place.c b/openbox/place.c index 276d9288..058bbfbe 100644 --- a/openbox/place.c +++ b/openbox/place.c @@ -407,21 +407,21 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y, g_free(areas); } - if (settings->center_x) + if (settings->position.x.center) *x = screen->x + screen->width / 2 - client->area.width / 2; - else if (settings->opposite_x) + else if (settings->position.x.opposite) *x = screen->x + screen->width - client->frame->area.width - - settings->position.x; + settings->position.x.pos; else - *x = screen->x + settings->position.x; + *x = screen->x + settings->position.x.pos; - if (settings->center_y) + if (settings->position.y.center) *y = screen->y + screen->height / 2 - client->area.height / 2; - else if (settings->opposite_y) + else if (settings->position.y.opposite) *y = screen->y + screen->height - client->frame->area.height - - settings->position.y; + settings->position.y.pos; else - *y = screen->y + settings->position.y; + *y = screen->y + settings->position.y.pos; g_free(screen); return TRUE; -- cgit v1.2.3 From 405d9a3e431b01a221be65f41bccb6c80c43b0a4 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 21:19:58 -0500 Subject: dont reparse the config file when the keyboard map changes. just rebind everything. yay for mika as inspiration --- openbox/event.c | 9 ++++++--- openbox/keyboard.c | 11 +++++++++-- openbox/keyboard.h | 2 ++ openbox/keytree.c | 12 ++++++++---- openbox/keytree.h | 1 + openbox/translate.c | 2 ++ 6 files changed, 28 insertions(+), 9 deletions(-) (limited to 'openbox') diff --git a/openbox/event.c b/openbox/event.c index 6b0ecdd7..bc59d67e 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -639,9 +639,12 @@ static void event_process(const XEvent *ec, gpointer data) else if (e->type == MapRequest) client_manage(window); else if (e->type == MappingNotify) { - /* keyboard layout changes, reconfigure openbox. need to restart the - modkeys system, but also to reload the key bindings. */ - ob_reconfigure(); + /* keyboard layout changes for modifier mapping changes. reload the + modifier map, and rebind all the key bindings as appropriate */ + ob_debug("Kepboard map changed. Reloading keyboard bindings.\n"); + modkeys_shutdown(TRUE); + modkeys_startup(TRUE); + keyboard_rebind(); } else if (e->type == ClientMessage) { /* This is for _NET_WM_REQUEST_FRAME_EXTENTS messages. They come for diff --git a/openbox/keyboard.c b/openbox/keyboard.c index 0aade9ab..eddda577 100644 --- a/openbox/keyboard.c +++ b/openbox/keyboard.c @@ -51,8 +51,9 @@ static void grab_keys(gboolean grab) if (grab) { p = curpos ? curpos->first_child : keyboard_firstnode; while (p) { - grab_key(p->key, p->state, RootWindow(ob_display, ob_screen), - GrabModeAsync); + if (p->key) + grab_key(p->key, p->state, RootWindow(ob_display, ob_screen), + GrabModeAsync); p = p->next_sibling; } if (curpos) @@ -264,6 +265,12 @@ void keyboard_event(ObClient *client, const XEvent *e) } } +void keyboard_rebind() +{ + tree_rebind(keyboard_firstnode); + grab_keys(TRUE); +} + void keyboard_startup(gboolean reconfig) { grab_keys(TRUE); diff --git a/openbox/keyboard.h b/openbox/keyboard.h index 1c55e050..995cdbc5 100644 --- a/openbox/keyboard.h +++ b/openbox/keyboard.h @@ -34,6 +34,8 @@ extern KeyBindingTree *keyboard_firstnode; void keyboard_startup(gboolean reconfig); void keyboard_shutdown(gboolean reconfig); +void keyboard_rebind(); + void keyboard_chroot(GList *keylist); gboolean keyboard_bind(GList *keylist, struct _ObActionsAct *action); void keyboard_unbind_all(); diff --git a/openbox/keytree.c b/openbox/keytree.c index fb26624d..714fffda 100644 --- a/openbox/keytree.c +++ b/openbox/keytree.c @@ -63,14 +63,18 @@ KeyBindingTree *tree_build(GList *keylist) g_strdup(kit->data)); /* deep copy */ ret->first_child = p; if (p != NULL) p->parent = ret; - if (!translate_key(it->data, &ret->state, &ret->key)) { - tree_destroy(ret); - return NULL; - } + translate_key(it->data, &ret->state, &ret->key); } return ret; } +void tree_rebind(KeyBindingTree *node) { + GList *it = g_list_last(node->keylist); + translate_key(it->data, &node->state, &node->key); + if (node->next_sibling) tree_rebind(node->next_sibling); + if (node->first_child) tree_rebind(node->first_child); +} + void tree_assimilate(KeyBindingTree *node) { KeyBindingTree *a, *b, *tmp, *last; diff --git a/openbox/keytree.h b/openbox/keytree.h index 391cb154..0307378d 100644 --- a/openbox/keytree.h +++ b/openbox/keytree.h @@ -41,6 +41,7 @@ KeyBindingTree *tree_build(GList *keylist); void tree_assimilate(KeyBindingTree *node); KeyBindingTree *tree_find(KeyBindingTree *search, gboolean *conflict); gboolean tree_chroot(KeyBindingTree *tree, GList *keylist); +void tree_rebind(KeyBindingTree *node); #endif diff --git a/openbox/translate.c b/openbox/translate.c index 21015578..b2ae7d67 100644 --- a/openbox/translate.c +++ b/openbox/translate.c @@ -111,6 +111,8 @@ gboolean translate_key(const gchar *str, guint *state, guint *keycode) parsed = g_strsplit(str, "-", -1); + *state = *keycode = 0; + /* first, find the key (last token) */ l = NULL; for (i = 0; parsed[i] != NULL; ++i) -- cgit v1.2.3 From 5d533d9fe2139bb0096482201e765c0905de5152 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 21:33:46 -0500 Subject: fix a small bug introduced that broke per-app placement --- openbox/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'openbox') diff --git a/openbox/config.c b/openbox/config.c index 7ec2b3e0..c094732e 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -227,7 +227,7 @@ static void parse_per_app_settings(ObParseInst *inst, xmlDocPtr doc, if (!parse_contains("default", doc, c)) { config_parse_gravity_coord(doc, c, &settings->position.x); - settings->pos_given = TRUE; + x_pos_given = TRUE; } if (x_pos_given && (c = parse_find_node("y", n->children))) -- cgit v1.2.3 From 669c7655be8fef885e2f5ea0b0d389046ebb6753 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Jan 2008 23:16:06 -0500 Subject: since the internal windows are in window_map now, it's possible we'll get them back when we check what window an event happened on. so don't abort if that happens anymore. --- openbox/event.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'openbox') diff --git a/openbox/event.c b/openbox/event.c index bc59d67e..04ecf383 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -475,10 +475,12 @@ static void event_process(const XEvent *ec, gpointer data) client = WINDOW_AS_CLIENT(obwin); break; case Window_Menu: - case Window_Internal: /* not to be used for events */ g_assert_not_reached(); break; + case Window_Internal: + /* we don't do anything with events directly on these windows */ + break; } } -- cgit v1.2.3 From 32c3a97f2e6d029cfb183deb03ebd6963166ead1 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sat, 12 Jan 2008 13:31:46 -0500 Subject: fix a copy/paste bug in placing the move&resize popup --- openbox/moveresize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'openbox') diff --git a/openbox/moveresize.c b/openbox/moveresize.c index 8dc122c7..675cbe9c 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -126,7 +126,7 @@ static void popup_coords(ObClient *c, const gchar *format, gint a, gint b) y = config_resize_popup_fixed.y.pos; if (config_resize_popup_fixed.y.center) - y = area->y + area->width/2; + y = area->y + area->height/2; else if (config_resize_popup_fixed.y.opposite) y = RECT_RIGHT(*area) - y; else -- cgit v1.2.3 From df73dfa049b9d0bb81e09b27ecf678dce9b46301 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sat, 12 Jan 2008 16:15:45 -0500 Subject: make the dock's hiding always have at least 1px on screen --- openbox/dock.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'openbox') diff --git a/openbox/dock.c b/openbox/dock.c index 9d4b56c4..ed8bed4b 100644 --- a/openbox/dock.c +++ b/openbox/dock.c @@ -227,8 +227,10 @@ void dock_configure(void) gint l, r, t, b; gint strw, strh; Rect *a; + gint hidesize; RrMargins(dock->a_frame, &l, &t, &r, &b); + hidesize = MAX(1, ob_rr_theme->obwidth); dock->area.width = dock->area.height = 0; @@ -361,51 +363,51 @@ void dock_configure(void) case OB_DIRECTION_NORTHWEST: switch (config_dock_orient) { case OB_ORIENTATION_HORZ: - dock->area.y -= dock->area.height - ob_rr_theme->obwidth; + dock->area.y -= dock->area.height - hidesize; break; case OB_ORIENTATION_VERT: - dock->area.x -= dock->area.width - ob_rr_theme->obwidth; + dock->area.x -= dock->area.width - hidesize; break; } break; case OB_DIRECTION_NORTH: - dock->area.y -= dock->area.height - ob_rr_theme->obwidth; + dock->area.y -= dock->area.height - hidesize; break; case OB_DIRECTION_NORTHEAST: switch (config_dock_orient) { case OB_ORIENTATION_HORZ: - dock->area.y -= dock->area.height - ob_rr_theme->obwidth; + dock->area.y -= dock->area.height - hidesize; break; case OB_ORIENTATION_VERT: - dock->area.x += dock->area.width - ob_rr_theme->obwidth; + dock->area.x += dock->area.width - hidesize; break; } break; case OB_DIRECTION_WEST: - dock->area.x -= dock->area.width - ob_rr_theme->obwidth; + dock->area.x -= dock->area.width - hidesize; break; case OB_DIRECTION_EAST: - dock->area.x += dock->area.width - ob_rr_theme->obwidth; + dock->area.x += dock->area.width - hidesize; break; case OB_DIRECTION_SOUTHWEST: switch (config_dock_orient) { case OB_ORIENTATION_HORZ: - dock->area.y += dock->area.height - ob_rr_theme->obwidth; + dock->area.y += dock->area.height - hidesize; break; case OB_ORIENTATION_VERT: - dock->area.x -= dock->area.width - ob_rr_theme->obwidth; + dock->area.x -= dock->area.width - hidesize; break; } break; case OB_DIRECTION_SOUTH: - dock->area.y += dock->area.height - ob_rr_theme->obwidth; + dock->area.y += dock->area.height - hidesize; break; case OB_DIRECTION_SOUTHEAST: switch (config_dock_orient) { case OB_ORIENTATION_HORZ: - dock->area.y += dock->area.height - ob_rr_theme->obwidth; + dock->area.y += dock->area.height - hidesize; break; case OB_ORIENTATION_VERT: - dock->area.x += dock->area.width - ob_rr_theme->obwidth; + dock->area.x += dock->area.width - hidesize; break; } break; @@ -414,8 +416,8 @@ void dock_configure(void) } if (!config_dock_floating && config_dock_hide) { - strw = ob_rr_theme->obwidth; - strh = ob_rr_theme->obwidth; + strw = hidesize; + strh = hidesize; } else { strw = dock->area.width; strh = dock->area.height; -- cgit v1.2.3 From 64905704e92deca4caa7e63954f236860418d370 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sat, 12 Jan 2008 18:36:49 +0100 Subject: Update --version output copyright year to 2008. --- openbox/openbox.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'openbox') diff --git a/openbox/openbox.c b/openbox/openbox.c index c7e28324..30a26609 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -470,9 +470,9 @@ static void print_version() { g_print("Openbox %s\n", PACKAGE_VERSION); g_print(_("Copyright (c)")); - g_print(" 2007 Mikael Magnusson\n"); + g_print(" 2008 Mikael Magnusson\n"); g_print(_("Copyright (c)")); - g_print(" 2003-2007 Dana Jansens\n\n"); + g_print(" 2003-2006 Dana Jansens\n\n"); g_print("This program comes with ABSOLUTELY NO WARRANTY.\n"); g_print("This is free software, and you are welcome to redistribute it\n"); g_print("under certain conditions. See the file COPYING for details.\n\n"); -- cgit v1.2.3 From 5148b839fefe16b54f26bc0d2c7a500127cf2725 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sun, 13 Jan 2008 02:50:34 -0500 Subject: sync when killing all keyboard grabs, so that we can be sure they are gone before proceeding (fixes a race condition when running things that want to grab the keyboard very quickly. yes, arch is that fast somehow..) --- openbox/event.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'openbox') diff --git a/openbox/event.c b/openbox/event.c index 04ecf383..44e0f532 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -1997,6 +1997,8 @@ void event_cancel_all_key_grabs(void) } else ungrab_passive_key(); + + XSync(ob_display, FALSE); } gboolean event_time_after(Time t1, Time t2) -- cgit v1.2.3 From 6dfc3c726a2164ba70cfac3df436ee035822bdb1 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sun, 13 Jan 2008 03:40:14 -0500 Subject: don't skip windows that are skip_taskbar unless they are normal typed.. i.e. if a dialog sets this don't skip it (gnome shutdown/logout dialogs don't get focused otherwise in arch linux) --- openbox/client.c | 2 ++ openbox/focus.c | 10 +++------- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'openbox') diff --git a/openbox/client.c b/openbox/client.c index 1e2040fd..22eb8403 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -450,6 +450,8 @@ void client_manage(Window window) g_free(monitor); monitor = NULL; + ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s\n", + activate ? "yes" : "no"); if (activate) { gboolean raise = FALSE; diff --git a/openbox/focus.c b/openbox/focus.c index df02cb76..a4eb2cfa 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -337,13 +337,9 @@ gboolean focus_valid_target(ObClient *ft, that can be focused instead */ !focus_target_has_siblings(ft, iconic_windows, all_desktops)))); - /* it's not set to skip the taskbar (unless it is a type that would be - expected to set this hint, or modal) */ - ok = ok && ((ft->type == OB_CLIENT_TYPE_DOCK || - ft->type == OB_CLIENT_TYPE_DESKTOP || - ft->type == OB_CLIENT_TYPE_TOOLBAR || - ft->type == OB_CLIENT_TYPE_MENU || - ft->type == OB_CLIENT_TYPE_UTILITY) || + /* it's not set to skip the taskbar (but this only applies to normal typed + windows, and is overridden if the window is modal) */ + ok = ok && (ft->type != OB_CLIENT_TYPE_NORMAL || ft->modal || !ft->skip_taskbar); -- cgit v1.2.3 From ed51baa95808ad0235e30d3c5215deca4b9faa6b Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 19:36:36 -0500 Subject: remove the visible window title hints when unmanaging a window. not all WMs set those and it messes them up, and we'll set them again appropriately, they don't need to be saved. --- openbox/client.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'openbox') diff --git a/openbox/client.c b/openbox/client.c index 22eb8403..5e4e52e7 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -762,6 +762,11 @@ void client_unmanage(ObClient *self) XMapWindow(ob_display, self->window); } + /* these should not be left on the window ever. other window managers + don't necessarily use them and it will mess them up (like compiz) */ + PROP_ERASE(self->window, net_wm_visible_name); + PROP_ERASE(self->window, net_wm_visible_icon_name); + /* update the list hints */ client_set_list(); -- cgit v1.2.3 From 26f34d3ba0794c09757393881610b552e7bbbbeb Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 19:54:30 -0500 Subject: resizing was defaulting to the topleft corner instead of to the auto-ness or something.. --- openbox/actions/resize.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'openbox') diff --git a/openbox/actions/resize.c b/openbox/actions/resize.c index 81901bdd..3714e38b 100644 --- a/openbox/actions/resize.c +++ b/openbox/actions/resize.c @@ -5,6 +5,7 @@ #include "openbox/frame.h" typedef struct { + gboolean corner_specified; guint32 corner; } Options; @@ -33,6 +34,8 @@ static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node) if ((n = parse_find_node("edge", node))) { gchar *s = parse_string(doc, n); + + o->corner_specified = TRUE; if (!g_ascii_strcasecmp(s, "top")) o->corner = prop_atoms.net_wm_moveresize_size_top; else if (!g_ascii_strcasecmp(s, "bottom")) @@ -49,6 +52,9 @@ static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node) o->corner = prop_atoms.net_wm_moveresize_size_bottomleft; else if (!g_ascii_strcasecmp(s, "bottomright")) o->corner = prop_atoms.net_wm_moveresize_size_bottomright; + else + o->corner_specified = FALSE; + g_free(s); } return o; @@ -72,7 +78,7 @@ static gboolean run_func(ObActionsData *data, gpointer options) if (!data->button) corner = prop_atoms.net_wm_moveresize_size_keyboard; - else if (o->corner) + else if (o->corner_specified) corner = o->corner; /* it was specified in the binding */ else corner = pick_corner(data->x, data->y, -- cgit v1.2.3 From d122c973ca78cd4ac4e17931269f31b0abfffbb0 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 20:00:08 -0500 Subject: fix the context given off by the borders in the br corner --- openbox/frame.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'openbox') diff --git a/openbox/frame.c b/openbox/frame.c index b49139ac..b0666b27 100644 --- a/openbox/frame.c +++ b/openbox/frame.c @@ -1438,9 +1438,9 @@ ObFrameContext frame_context(ObClient *client, Window win, gint x, gint y) if (win == self->lgripbottom) return OB_FRAME_CONTEXT_BLCORNER; if (win == self->handleright) return OB_FRAME_CONTEXT_BRCORNER; if (win == self->rgrip) return OB_FRAME_CONTEXT_BRCORNER; - if (win == self->rgripright) return OB_FRAME_CONTEXT_BLCORNER; - if (win == self->rgriptop) return OB_FRAME_CONTEXT_BLCORNER; - if (win == self->rgripbottom) return OB_FRAME_CONTEXT_BLCORNER; + if (win == self->rgripright) return OB_FRAME_CONTEXT_BRCORNER; + if (win == self->rgriptop) return OB_FRAME_CONTEXT_BRCORNER; + if (win == self->rgripbottom) return OB_FRAME_CONTEXT_BRCORNER; if (win == self->title) return OB_FRAME_CONTEXT_TITLEBAR; if (win == self->titlebottom) return OB_FRAME_CONTEXT_TITLEBAR; if (win == self->titleleft) return OB_FRAME_CONTEXT_TLCORNER; -- cgit v1.2.3 From 2b5d4b69974aba63f0c22cd5e4b91c456cd70f68 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 20:33:56 -0500 Subject: the inner border's corners weren't having events handled on them correctly, which was messing with resizing. yay akk for finding this. --- openbox/frame.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'openbox') diff --git a/openbox/frame.c b/openbox/frame.c index b0666b27..a47c2f06 100644 --- a/openbox/frame.c +++ b/openbox/frame.c @@ -1007,6 +1007,10 @@ void frame_grab_client(ObFrame *self) g_hash_table_insert(window_map, &self->innertop, self->client); g_hash_table_insert(window_map, &self->innerright, self->client); g_hash_table_insert(window_map, &self->innerbottom, self->client); + g_hash_table_insert(window_map, &self->innerblb, self->client); + g_hash_table_insert(window_map, &self->innerbll, self->client); + g_hash_table_insert(window_map, &self->innerbrb, self->client); + g_hash_table_insert(window_map, &self->innerbrr, self->client); g_hash_table_insert(window_map, &self->title, self->client); g_hash_table_insert(window_map, &self->label, self->client); g_hash_table_insert(window_map, &self->max, self->client); @@ -1087,6 +1091,10 @@ void frame_release_client(ObFrame *self) g_hash_table_remove(window_map, &self->innertop); g_hash_table_remove(window_map, &self->innerright); g_hash_table_remove(window_map, &self->innerbottom); + g_hash_table_remove(window_map, &self->innerblb); + g_hash_table_remove(window_map, &self->innerbll); + g_hash_table_remove(window_map, &self->innerbrb); + g_hash_table_remove(window_map, &self->innerbrr); g_hash_table_remove(window_map, &self->title); g_hash_table_remove(window_map, &self->label); g_hash_table_remove(window_map, &self->max); @@ -1459,6 +1467,10 @@ ObFrameContext frame_context(ObClient *client, Window win, gint x, gint y) if (win == self->innerleft) return OB_FRAME_CONTEXT_LEFT; if (win == self->innerbottom) return OB_FRAME_CONTEXT_BOTTOM; if (win == self->innerright) return OB_FRAME_CONTEXT_RIGHT; + if (win == self->innerbll) return OB_FRAME_CONTEXT_BLCORNER; + if (win == self->innerblb) return OB_FRAME_CONTEXT_BLCORNER; + if (win == self->innerbrr) return OB_FRAME_CONTEXT_BRCORNER; + if (win == self->innerbrb) return OB_FRAME_CONTEXT_BRCORNER; if (win == self->max) return OB_FRAME_CONTEXT_MAXIMIZE; if (win == self->iconify) return OB_FRAME_CONTEXT_ICONIFY; if (win == self->close) return OB_FRAME_CONTEXT_CLOSE; -- cgit v1.2.3 From d790dc162d24cfdcc236114b50c51af62612646a Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 20:48:28 -0500 Subject: check if a client will respond to pings --- openbox/client.c | 4 ++++ openbox/client.h | 3 +++ openbox/prop.c | 2 +- openbox/prop.h | 2 +- 4 files changed, 9 insertions(+), 2 deletions(-) (limited to 'openbox') diff --git a/openbox/client.c b/openbox/client.c index 5e4e52e7..7019f690 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -1507,6 +1507,10 @@ void client_update_protocols(ObClient *self) /* if this protocol is requested, then the window will be notified whenever we want it to receive focus */ self->focus_notify = TRUE; + else if (proto[i] == prop_atoms.net_wm_ping) + /* if this protocol is requested, then the window will allow + pings to determine if it is still alive */ + self->ping = TRUE; #ifdef SYNC else if (proto[i] == prop_atoms.net_wm_sync_request) /* if this protocol is requested, then resizing the diff --git a/openbox/client.h b/openbox/client.h index e83a6b7a..49ff72bc 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -220,6 +220,9 @@ struct _ObClient /*! Notify the window when it receives focus? */ gboolean focus_notify; + /*! Will the client respond to pings? */ + gboolean ping; + #ifdef SYNC /*! The client wants to sync during resizes */ gboolean sync_request; diff --git a/openbox/prop.c b/openbox/prop.c index 44abdfe6..1e343e16 100644 --- a/openbox/prop.c +++ b/openbox/prop.c @@ -98,7 +98,7 @@ void prop_startup(void) CREATE(kde_net_wm_frame_strut, "_KDE_NET_WM_FRAME_STRUT"); CREATE(net_frame_extents, "_NET_FRAME_EXTENTS"); -/* CREATE(net_wm_ping, "_NET_WM_PING"); */ + CREATE(net_wm_ping, "_NET_WM_PING"); #ifdef SYNC CREATE(net_wm_sync_request, "_NET_WM_SYNC_REQUEST"); CREATE(net_wm_sync_request_counter, "_NET_WM_SYNC_REQUEST_COUNTER"); diff --git a/openbox/prop.h b/openbox/prop.h index f0c4f5e9..fd12f98a 100644 --- a/openbox/prop.h +++ b/openbox/prop.h @@ -136,7 +136,7 @@ typedef struct Atoms { Atom net_frame_extents; /* application protocols */ -/* Atom net_wm_ping; */ + Atom net_wm_ping; #ifdef SYNC Atom net_wm_sync_request; Atom net_wm_sync_request_counter; -- cgit v1.2.3 From fb7a71da202632c7301ada67c8b4420bfb8d8fbe Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 21:40:15 -0500 Subject: can tell when a window that was "closed" has stopped responding now --- openbox/client.c | 26 ++++----- openbox/event.c | 3 ++ openbox/mainloop.c | 4 +- openbox/ping.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++ openbox/ping.h | 41 +++++++++++++++ openbox/prop.c | 13 +++-- openbox/prop.h | 8 +++ 7 files changed, 229 insertions(+), 17 deletions(-) create mode 100644 openbox/ping.c create mode 100644 openbox/ping.h (limited to 'openbox') diff --git a/openbox/client.c b/openbox/client.c index 7019f690..0f592ebe 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -3166,10 +3166,16 @@ void client_shade(ObClient *self, gboolean shade) frame_adjust_area(self->frame, FALSE, TRUE, FALSE); } -void client_close(ObClient *self) +static void client_ping_event(ObClient *self, gboolean dead) { - XEvent ce; + if (dead) + ob_debug("client 0x%x window 0x%x is not responding !!\n"); + else + ob_debug("client 0x%x window 0x%x started responding again..\n"); +} +void client_close(ObClient *self) +{ if (!(self->functions & OB_CLIENT_FUNC_CLOSE)) return; /* in the case that the client provides no means to requesting that it @@ -3185,17 +3191,11 @@ void client_close(ObClient *self) explicitly killed. */ - ce.xclient.type = ClientMessage; - ce.xclient.message_type = prop_atoms.wm_protocols; - ce.xclient.display = ob_display; - ce.xclient.window = self->window; - ce.xclient.format = 32; - ce.xclient.data.l[0] = prop_atoms.wm_delete_window; - ce.xclient.data.l[1] = event_curtime; - ce.xclient.data.l[2] = 0l; - ce.xclient.data.l[3] = 0l; - ce.xclient.data.l[4] = 0l; - XSendEvent(ob_display, self->window, FALSE, NoEventMask, &ce); + PROP_MSG_TO(self->window, self->window, wm_protocols, + prop_atoms.wm_delete_window, event_curtime, 0, 0, 0, + NoEventMask); + + ping_start(self, client_ping_event); } void client_kill(ObClient *self) diff --git a/openbox/event.c b/openbox/event.c index 44e0f532..5d85eaeb 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -767,6 +767,9 @@ static void event_handle_root(XEvent *e) ob_restart(); else if (e->xclient.data.l[0] == 3) ob_exit(0); + } else if (msgtype == prop_atoms.wm_protocols) { + if (e->xclient.data.l[0] == prop_atoms.net_wm_ping) + ping_got_pong(e->xclient.data.l[1]); } break; case PropertyNotify: diff --git a/openbox/mainloop.c b/openbox/mainloop.c index 7c6a9566..c1ede830 100644 --- a/openbox/mainloop.c +++ b/openbox/mainloop.c @@ -560,7 +560,9 @@ void ob_main_loop_timeout_remove_data(ObMainLoop *loop, GSourceFunc handler, for (it = loop->timers; it; it = g_slist_next(it)) { ObMainLoopTimer *t = it->data; - if (t->func == handler && t->equal(t->data, data)) { + if (t->func == handler && + (t->equal ? t->equal(t->data, data) : (t->data == data))) + { t->del_me = TRUE; if (cancel_dest) t->destroy = NULL; diff --git a/openbox/ping.c b/openbox/ping.c new file mode 100644 index 00000000..d8c10c83 --- /dev/null +++ b/openbox/ping.c @@ -0,0 +1,151 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + client.h for the Openbox window manager + Copyright (c) 2006 Mikael Magnusson + Copyright (c) 2003-2008 Dana Jansens + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + See the COPYING file for a copy of the GNU General Public License. +*/ + +#include "ping.h" +#include "client.h" +#include "prop.h" +#include "event.h" +#include "mainloop.h" +#include "openbox.h" + +typedef struct _ObPingTarget +{ + ObClient *client; + ObPingEventHandler h; + Time sent; + gint waiting; +} ObPingTarget; + +static GSList *ping_targets = NULL; +static gboolean active = FALSE; + +#define PING_TIMEOUT (G_USEC_PER_SEC * 1) +/*! Warn the user after this many PING_TIMEOUT intervals */ +#define PING_TIMEOUT_WARN 3 + +static void ping_send(ObPingTarget *t); +static void ping_end(ObClient *client, gpointer data); +static gboolean ping_timeout(gpointer data); + +void ping_start(struct _ObClient *client, ObPingEventHandler h) +{ + GSList *it; + ObPingTarget *t; + + /* make sure we're not already pinging it */ + for (it = ping_targets; it != NULL; it = g_slist_next(it)) { + t = it->data; + if (t->client == client) return; + } + + t = g_new(ObPingTarget, 1); + t->client = client; + t->h = h; + t->waiting = 1; /* first wait for a reply */ + + ping_send(t); + ping_targets = g_slist_prepend(ping_targets, t); + ob_main_loop_timeout_add(ob_main_loop, PING_TIMEOUT, ping_timeout, + t, NULL, NULL); + + if (!active) { + active = TRUE; + /* listen for the client to disappear */ + client_add_destroy_notify(ping_end, NULL); + } +} + +void ping_stop(struct _ObClient *c) +{ + ping_end(c, NULL); +} + +void ping_got_pong(Time timestamp) +{ + GSList *it; + ObPingTarget *t; + + /* make sure we're not already pinging it */ + for (it = ping_targets; it != NULL; it = g_slist_next(it)) { + t = it->data; + if (t->sent == timestamp) { + ob_debug("Got PONG with timestamp %lu\n", timestamp); + if (t->waiting > PING_TIMEOUT_WARN) { + /* we had notified that they weren't responding, so now we + need to notify that they are again */ + t->h(t->client, FALSE); + } + t->waiting = 0; /* not waiting for a reply anymore */ + break; + } + } + + if (it == NULL) + ob_debug("Got PONG with timestamp %lu but not waiting for one\n", + timestamp); +} + +static void ping_send(ObPingTarget *t) +{ + t->sent = event_get_server_time(); + ob_debug("PINGing client 0x%x at %lu\n", t->client->window, t->sent); + PROP_MSG_TO(t->client->window, t->client->window, wm_protocols, + prop_atoms.net_wm_ping, t->sent, t->client->window, 0, 0, + NoEventMask); +} + +static gboolean ping_timeout(gpointer data) +{ + ObPingTarget *t = data; + + if (t->waiting == 0) { /* got a reply already */ + /* send another ping to make sure it's still alive */ + ping_send(t); + } + + if (t->waiting == PING_TIMEOUT_WARN) + t->h(t->client, TRUE); /* notify that the client isn't responding */ + + ++t->waiting; + + return TRUE; /* repeat */ +} + +static void ping_end(ObClient *client, gpointer data) +{ + GSList *it; + ObPingTarget *t; + + for (it = ping_targets; it != NULL; it = g_slist_next(it)) { + t = it->data; + if (t->client == client) { + ping_targets = g_slist_remove_link(ping_targets, it); + ob_main_loop_timeout_remove_data(ob_main_loop, ping_timeout, t, + FALSE); + g_free(t); + break; + } + } + + /* stop listening if we're not waiting for any more pings */ + if (!ping_targets) { + active = TRUE; + client_remove_destroy_notify(ping_end); + } +} diff --git a/openbox/ping.h b/openbox/ping.h new file mode 100644 index 00000000..0b6dfead --- /dev/null +++ b/openbox/ping.h @@ -0,0 +1,41 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + client.h for the Openbox window manager + Copyright (c) 2006 Mikael Magnusson + Copyright (c) 2003-2008 Dana Jansens + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + See the COPYING file for a copy of the GNU General Public License. +*/ + +#ifndef __ping_h +#define __ping_h + +#include +#include + +struct _ObClient; + +/*! + Notifies when the client application isn't responding to pings, or when it + starts responding again. + @param dead TRUE if the app isn't responding, FALSE if it starts responding + again +*/ +typedef void (*ObPingEventHandler) (struct _ObClient *c, gboolean dead); + +void ping_start(struct _ObClient *c, ObPingEventHandler h); +void ping_stop(struct _ObClient *c); + +void ping_got_pong(Time timestamp); + +#endif diff --git a/openbox/prop.c b/openbox/prop.c index 1e343e16..b43dcd13 100644 --- a/openbox/prop.c +++ b/openbox/prop.c @@ -446,6 +446,14 @@ void prop_erase(Window win, Atom prop) void prop_message(Window about, Atom messagetype, glong data0, glong data1, glong data2, glong data3, glong mask) +{ + prop_message_to(RootWindow(ob_display, ob_screen), about, messagetype, + data0, data1, data2, data3, 0, mask); +} + +void prop_message_to(Window to, Window about, Atom messagetype, + glong data0, glong data1, glong data2, + glong data3, glong data4, glong mask) { XEvent ce; ce.xclient.type = ClientMessage; @@ -457,7 +465,6 @@ void prop_message(Window about, Atom messagetype, glong data0, glong data1, ce.xclient.data.l[1] = data1; ce.xclient.data.l[2] = data2; ce.xclient.data.l[3] = data3; - ce.xclient.data.l[4] = 0; - XSendEvent(ob_display, RootWindow(ob_display, ob_screen), FALSE, - mask, &ce); + ce.xclient.data.l[4] = data4; + XSendEvent(ob_display, to, FALSE, mask, &ce); } diff --git a/openbox/prop.h b/openbox/prop.h index fd12f98a..13c338ef 100644 --- a/openbox/prop.h +++ b/openbox/prop.h @@ -218,6 +218,9 @@ void prop_erase(Window win, Atom prop); void prop_message(Window about, Atom messagetype, glong data0, glong data1, glong data2, glong data3, glong mask); +void prop_message_to(Window to, Window about, Atom messagetype, + glong data0, glong data1, glong data2, + glong data3, glong data4, glong mask); #define PROP_GET32(win, prop, type, ret) \ (prop_get32(win, prop_atoms.prop, prop_atoms.type, ret)) @@ -244,4 +247,9 @@ void prop_message(Window about, Atom messagetype, glong data0, glong data1, (prop_message(about, prop_atoms.msgtype, data0, data1, data2, data3, \ SubstructureNotifyMask | SubstructureRedirectMask)) +#define PROP_MSG_TO(to, about, msgtype, data0, data1, data2, data3, data4, \ + mask) \ + (prop_message_to(to, about, prop_atoms.msgtype, \ + data0, data1, data2, data3, data4, mask)) + #endif -- cgit v1.2.3 From d3e9fc8941831477b50678b9bd676e29f4bed1a7 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 21:57:47 -0500 Subject: show [Not Responding] in the titlebar when closing an app and it stops responding to pings --- openbox/client.c | 23 ++++++++++++++++++----- openbox/client.h | 3 +++ openbox/ping.c | 2 ++ 3 files changed, 23 insertions(+), 5 deletions(-) (limited to 'openbox') diff --git a/openbox/client.c b/openbox/client.c index 0f592ebe..a4d045dc 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -40,6 +40,7 @@ #include "keyboard.h" #include "mouse.h" #include "render/render.h" +#include "gettext.h" #ifdef HAVE_UNISTD_H # include @@ -93,6 +94,7 @@ static GSList *client_search_all_top_parents_internal(ObClient *self, gboolean bylayer, ObStackingLayer layer); static void client_call_notifies(ObClient *self, GSList *list); +static void client_ping_event(ObClient *self, gboolean dead); void client_startup(gboolean reconfig) @@ -1947,6 +1949,12 @@ void client_update_title(ObClient *self) } else visible = data; + if (self->not_responding) { + data = visible; + visible = g_strdup_printf("%s - [%s]", data, _("Not Responding")); + g_free(data); + } + PROP_SETS(self->window, net_wm_visible_name, visible); self->title = visible; @@ -1970,6 +1978,12 @@ void client_update_title(ObClient *self) } else visible = data; + if (self->not_responding) { + data = visible; + visible = g_strdup_printf("%s - [%s]", data, _("Not Responding")); + g_free(data); + } + PROP_SETS(self->window, net_wm_visible_icon_name, visible); self->icon_title = visible; } @@ -3168,10 +3182,8 @@ void client_shade(ObClient *self, gboolean shade) static void client_ping_event(ObClient *self, gboolean dead) { - if (dead) - ob_debug("client 0x%x window 0x%x is not responding !!\n"); - else - ob_debug("client 0x%x window 0x%x started responding again..\n"); + self->not_responding = dead; + client_update_title(self); } void client_close(ObClient *self) @@ -3195,7 +3207,8 @@ void client_close(ObClient *self) prop_atoms.wm_delete_window, event_curtime, 0, 0, 0, NoEventMask); - ping_start(self, client_ping_event); + if (self->ping) + ping_start(self, client_ping_event); } void client_kill(ObClient *self) diff --git a/openbox/client.h b/openbox/client.h index 49ff72bc..672b3822 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -222,6 +222,9 @@ struct _ObClient /*! Will the client respond to pings? */ gboolean ping; + /*! Indicates if the client is trying to close but has stopped responding + to pings */ + gboolean not_responding; #ifdef SYNC /*! The client wants to sync during resizes */ diff --git a/openbox/ping.c b/openbox/ping.c index d8c10c83..687dd7f4 100644 --- a/openbox/ping.c +++ b/openbox/ping.c @@ -48,6 +48,8 @@ void ping_start(struct _ObClient *client, ObPingEventHandler h) GSList *it; ObPingTarget *t; + g_assert(client->ping == TRUE); + /* make sure we're not already pinging it */ for (it = ping_targets; it != NULL; it = g_slist_next(it)) { t = it->data; -- cgit v1.2.3 From 07994cb2dcafe33db99da5f7234caefdc0baa809 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 22:00:21 -0500 Subject: when you close a window that you already tried to close and its not responding to pings, then do a kill the next time --- openbox/client.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'openbox') diff --git a/openbox/client.c b/openbox/client.c index a4d045dc..517482c7 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -3195,20 +3195,16 @@ void client_close(ObClient *self) if (!self->delete_window) client_kill(self); - /* - XXX: itd be cool to do timeouts and shit here for killing the client's - process off - like... if the window is around after 5 seconds, then the close button - turns a nice red, and if this function is called again, the client is - explicitly killed. - */ - - PROP_MSG_TO(self->window, self->window, wm_protocols, - prop_atoms.wm_delete_window, event_curtime, 0, 0, 0, - NoEventMask); + if (self->not_responding) + client_kill(self); + else { + PROP_MSG_TO(self->window, self->window, wm_protocols, + prop_atoms.wm_delete_window, event_curtime, 0, 0, 0, + NoEventMask); - if (self->ping) - ping_start(self, client_ping_event); + if (self->ping) + ping_start(self, client_ping_event); + } } void client_kill(ObClient *self) -- cgit v1.2.3 From e6d33facc8f02a068f62b4f60c2872589b620dab Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 22:13:16 -0500 Subject: when you close an app and it stops responding.. if you hit close again, it will try kill -TERM. if that fails and you close again, it will kill -9 ! (assuming the app is running on the local host and provided its PID) --- openbox/client.c | 29 +++++++++++++++++++++++++---- openbox/client.h | 8 ++++++++ openbox/prop.c | 2 +- openbox/prop.h | 2 +- 4 files changed, 35 insertions(+), 6 deletions(-) (limited to 'openbox') diff --git a/openbox/client.c b/openbox/client.c index 517482c7..d768ecc1 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -46,6 +46,10 @@ # include #endif +#ifdef HAVE_SIGNAL_H +# include /* for kill() */ +#endif + #include #include @@ -2244,6 +2248,7 @@ static void client_get_session_ids(ObClient *self) if (got) { gchar localhost[128]; + guint32 pid; gethostname(localhost, 127); localhost[127] = '\0'; @@ -2251,6 +2256,11 @@ static void client_get_session_ids(ObClient *self) self->client_machine = s; else g_free(s); + + /* see if it has the PID set too (the PID requires that the + WM_CLIENT_MACHINE be set) */ + if (PROP_GET32(self->window, net_wm_pid, cardinal, &pid)) + self->pid = pid; } } @@ -3193,9 +3203,10 @@ void client_close(ObClient *self) /* in the case that the client provides no means to requesting that it close, we just kill it */ if (!self->delete_window) - client_kill(self); - - if (self->not_responding) + /* don't use client_kill(), we should only kill based on PID in + response to a lack of PING replies */ + XKillClient(ob_display, self->window); + else if (self->not_responding) client_kill(self); else { PROP_MSG_TO(self->window, self->window, wm_protocols, @@ -3209,7 +3220,17 @@ void client_close(ObClient *self) void client_kill(ObClient *self) { - XKillClient(ob_display, self->window); + if (!self->client_machine && self->pid) { + /* running on the local host */ + if (!self->kill_tried_term) { + kill(self->pid, SIGTERM); + self->kill_tried_term = TRUE; + } + else + kill(self->pid, SIGKILL); /* kill -9 */ + } + else + XKillClient(ob_display, self->window); } void client_hilite(ObClient *self, gboolean hilite) diff --git a/openbox/client.h b/openbox/client.h index 672b3822..f568b008 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -30,6 +30,10 @@ #include #include +#ifdef HAVE_SYS_TYPES_H +# include /* for pid_t */ +#endif + struct _ObFrame; struct _ObGroup; struct _ObSessionState; @@ -115,6 +119,8 @@ struct _ObClient gchar *client_machine; /*! The command used to run the program. Pre-XSMP window identification. */ gchar *wm_command; + /*! The PID of the process which owns the window */ + pid_t pid; /*! The application that created the window */ gchar *name; @@ -225,6 +231,8 @@ struct _ObClient /*! Indicates if the client is trying to close but has stopped responding to pings */ gboolean not_responding; + /*! We tried to kill the client with SIGTERM */ + gboolean kill_tried_term; #ifdef SYNC /*! The client wants to sync during resizes */ diff --git a/openbox/prop.c b/openbox/prop.c index b43dcd13..c4b8baea 100644 --- a/openbox/prop.c +++ b/openbox/prop.c @@ -91,7 +91,7 @@ void prop_startup(void) CREATE(net_wm_strut_partial, "_NET_WM_STRUT_PARTIAL"); CREATE(net_wm_icon, "_NET_WM_ICON"); CREATE(net_wm_icon_geometry, "_NET_WM_ICON_GEOMETRY"); -/* CREATE(net_wm_pid, "_NET_WM_PID"); */ + CREATE(net_wm_pid, "_NET_WM_PID"); CREATE(net_wm_allowed_actions, "_NET_WM_ALLOWED_ACTIONS"); CREATE(net_wm_user_time, "_NET_WM_USER_TIME"); /* CREATE(net_wm_user_time_window, "_NET_WM_USER_TIME_WINDOW"); */ diff --git a/openbox/prop.h b/openbox/prop.h index 13c338ef..92884144 100644 --- a/openbox/prop.h +++ b/openbox/prop.h @@ -129,7 +129,7 @@ typedef struct Atoms { Atom net_wm_strut_partial; Atom net_wm_icon; Atom net_wm_icon_geometry; -/* Atom net_wm_pid; */ + Atom net_wm_pid; Atom net_wm_allowed_actions; Atom net_wm_user_time; /* Atom net_wm_user_time_window; */ -- cgit v1.2.3 From dbce9ee24320baa01e62d88485fb536c8d9a5e55 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 22:15:45 -0500 Subject: its possible we did kill -TERM and it stayed alive and started responding again, so handle that case --- openbox/client.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'openbox') diff --git a/openbox/client.c b/openbox/client.c index d768ecc1..5443b158 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -3213,8 +3213,13 @@ void client_close(ObClient *self) prop_atoms.wm_delete_window, event_curtime, 0, 0, 0, NoEventMask); - if (self->ping) + if (self->ping) { + /* may have tried to kill it earlier but the window is still + around and started responding again */ + self->kill_tried_term = FALSE; + ping_start(self, client_ping_event); + } } } -- cgit v1.2.3 From 810afd8597da355039e289218abed6c062585870 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 22:34:04 -0500 Subject: ping all the windows every 3 seconds, and show "not responding" if they stop replying for 3 times (9-12 seconds). show [Killing...] in the titlebar when trying to kill an app off --- openbox/client.c | 50 ++++++++++++++++++++++++++++++++++++-------------- openbox/client.h | 6 ++++-- openbox/ping.c | 6 +++--- 3 files changed, 43 insertions(+), 19 deletions(-) (limited to 'openbox') diff --git a/openbox/client.c b/openbox/client.c index 5443b158..85f5e691 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -602,6 +602,9 @@ void client_manage(Window window) /* update the list hints */ client_set_list(); + /* watch for when the application stops responding */ + if (self->ping) ping_start(self, client_ping_event); + /* free the ObAppSettings shallow copy */ g_free(settings); @@ -683,6 +686,9 @@ void client_unmanage(ObClient *self) /* remove the window from our save set */ XChangeSaveSet(ob_display, self->window, SetModeDelete); + /* stop pinging the window */ + if (self->ping) ping_stop(self); + /* update the focus lists */ focus_order_remove(self); if (client_focused(self)) { @@ -1955,7 +1961,10 @@ void client_update_title(ObClient *self) if (self->not_responding) { data = visible; - visible = g_strdup_printf("%s - [%s]", data, _("Not Responding")); + if (self->close_tried_term) + visible = g_strdup_printf("%s - [%s]", data, _("Killing...")); + else + visible = g_strdup_printf("%s - [%s]", data, _("Not Responding")); g_free(data); } @@ -1984,7 +1993,10 @@ void client_update_title(ObClient *self) if (self->not_responding) { data = visible; - visible = g_strdup_printf("%s - [%s]", data, _("Not Responding")); + if (self->close_tried_term) + visible = g_strdup_printf("%s - [%s]", data, _("Killing...")); + else + visible = g_strdup_printf("%s - [%s]", data, _("Not Responding")); g_free(data); } @@ -3194,6 +3206,14 @@ static void client_ping_event(ObClient *self, gboolean dead) { self->not_responding = dead; client_update_title(self); + + if (!dead) { + /* the window has started responding again, so don't kill it the first + time they click on close, even if it stops responding again in the + future */ + self->close_tried_destroy = FALSE; + self->close_tried_term = FALSE; + } } void client_close(ObClient *self) @@ -3206,20 +3226,14 @@ void client_close(ObClient *self) /* don't use client_kill(), we should only kill based on PID in response to a lack of PING replies */ XKillClient(ob_display, self->window); - else if (self->not_responding) + else if (self->not_responding && self->close_tried_destroy) client_kill(self); else { PROP_MSG_TO(self->window, self->window, wm_protocols, prop_atoms.wm_delete_window, event_curtime, 0, 0, 0, NoEventMask); - - if (self->ping) { - /* may have tried to kill it earlier but the window is still - around and started responding again */ - self->kill_tried_term = FALSE; - - ping_start(self, client_ping_event); - } + self->close_tried_destroy = TRUE; + self->close_tried_term = FALSE; } } @@ -3227,12 +3241,20 @@ void client_kill(ObClient *self) { if (!self->client_machine && self->pid) { /* running on the local host */ - if (!self->kill_tried_term) { + if (!self->close_tried_term) { + ob_debug("killing window 0x%x with pid %lu, with SIGTERM\n", + self->window, self->pid); kill(self->pid, SIGTERM); - self->kill_tried_term = TRUE; + self->close_tried_term = TRUE; + + /* show that we're trying to kill it */ + client_update_title(self); } - else + else { + ob_debug("killing window 0x%x with pid %lu, with SIGKILL\n", + self->window, self->pid); kill(self->pid, SIGKILL); /* kill -9 */ + } } else XKillClient(ob_display, self->window); diff --git a/openbox/client.h b/openbox/client.h index f568b008..b9dd9e5a 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -231,8 +231,10 @@ struct _ObClient /*! Indicates if the client is trying to close but has stopped responding to pings */ gboolean not_responding; - /*! We tried to kill the client with SIGTERM */ - gboolean kill_tried_term; + /*! We tried to close the window with a DESTROY message */ + gboolean close_tried_destroy; + /*! We tried to close the window with a SIGTERM */ + gboolean close_tried_term; #ifdef SYNC /*! The client wants to sync during resizes */ diff --git a/openbox/ping.c b/openbox/ping.c index 687dd7f4..874d020c 100644 --- a/openbox/ping.c +++ b/openbox/ping.c @@ -35,7 +35,7 @@ typedef struct _ObPingTarget static GSList *ping_targets = NULL; static gboolean active = FALSE; -#define PING_TIMEOUT (G_USEC_PER_SEC * 1) +#define PING_TIMEOUT (G_USEC_PER_SEC * 3) /*! Warn the user after this many PING_TIMEOUT intervals */ #define PING_TIMEOUT_WARN 3 @@ -87,7 +87,7 @@ void ping_got_pong(Time timestamp) for (it = ping_targets; it != NULL; it = g_slist_next(it)) { t = it->data; if (t->sent == timestamp) { - ob_debug("Got PONG with timestamp %lu\n", timestamp); + /*ob_debug("Got PONG with timestamp %lu\n", timestamp);*/ if (t->waiting > PING_TIMEOUT_WARN) { /* we had notified that they weren't responding, so now we need to notify that they are again */ @@ -106,7 +106,7 @@ void ping_got_pong(Time timestamp) static void ping_send(ObPingTarget *t) { t->sent = event_get_server_time(); - ob_debug("PINGing client 0x%x at %lu\n", t->client->window, t->sent); + /*ob_debug("PINGing client 0x%x at %lu\n", t->client->window, t->sent);*/ PROP_MSG_TO(t->client->window, t->client->window, wm_protocols, prop_atoms.net_wm_ping, t->sent, t->client->window, 0, 0, NoEventMask); -- cgit v1.2.3 From d5c824cfd4ec84155772a5c482b0ffdc99dc1ab9 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 22:36:45 -0500 Subject: only ping windows that we need to --- openbox/client.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'openbox') diff --git a/openbox/client.c b/openbox/client.c index 85f5e691..1f7ce97b 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -602,8 +602,11 @@ void client_manage(Window window) /* update the list hints */ client_set_list(); - /* watch for when the application stops responding */ - if (self->ping) ping_start(self, client_ping_event); + /* watch for when the application stops responding. only do this for + normal windows, i.e. windows which have titlebars and close buttons + and things like that */ + if (self->ping && client_normal(self)) + ping_start(self, client_ping_event); /* free the ObAppSettings shallow copy */ g_free(settings); @@ -687,7 +690,8 @@ void client_unmanage(ObClient *self) XChangeSaveSet(ob_display, self->window, SetModeDelete); /* stop pinging the window */ - if (self->ping) ping_stop(self); + if (self->ping && client_normal(self)) + ping_stop(self); /* update the focus lists */ focus_order_remove(self); -- cgit v1.2.3 From f9f32d9fbaae9ca415603bb61b36393994afbd16 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 22:51:04 -0500 Subject: cant consistently tell if we should use WM_DESTROY after the first time they try close a window.. so just kill when "not responding" is showing --- openbox/client.c | 10 +++------- openbox/client.h | 2 -- openbox/ping.c | 5 +++-- 3 files changed, 6 insertions(+), 11 deletions(-) (limited to 'openbox') diff --git a/openbox/client.c b/openbox/client.c index 1f7ce97b..2f8f58a9 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -3212,10 +3212,8 @@ static void client_ping_event(ObClient *self, gboolean dead) client_update_title(self); if (!dead) { - /* the window has started responding again, so don't kill it the first - time they click on close, even if it stops responding again in the - future */ - self->close_tried_destroy = FALSE; + /* try kill it nicely the first time again, if it started responding + at some point */ self->close_tried_term = FALSE; } } @@ -3230,14 +3228,12 @@ void client_close(ObClient *self) /* don't use client_kill(), we should only kill based on PID in response to a lack of PING replies */ XKillClient(ob_display, self->window); - else if (self->not_responding && self->close_tried_destroy) + else if (self->not_responding) client_kill(self); else { PROP_MSG_TO(self->window, self->window, wm_protocols, prop_atoms.wm_delete_window, event_curtime, 0, 0, 0, NoEventMask); - self->close_tried_destroy = TRUE; - self->close_tried_term = FALSE; } } diff --git a/openbox/client.h b/openbox/client.h index b9dd9e5a..0efeb197 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -231,8 +231,6 @@ struct _ObClient /*! Indicates if the client is trying to close but has stopped responding to pings */ gboolean not_responding; - /*! We tried to close the window with a DESTROY message */ - gboolean close_tried_destroy; /*! We tried to close the window with a SIGTERM */ gboolean close_tried_term; diff --git a/openbox/ping.c b/openbox/ping.c index 874d020c..531b8938 100644 --- a/openbox/ping.c +++ b/openbox/ping.c @@ -87,7 +87,8 @@ void ping_got_pong(Time timestamp) for (it = ping_targets; it != NULL; it = g_slist_next(it)) { t = it->data; if (t->sent == timestamp) { - /*ob_debug("Got PONG with timestamp %lu\n", timestamp);*/ + ob_debug("Got PONG with timestamp %lu for %s\n", timestamp, + t->client->title); if (t->waiting > PING_TIMEOUT_WARN) { /* we had notified that they weren't responding, so now we need to notify that they are again */ @@ -106,7 +107,7 @@ void ping_got_pong(Time timestamp) static void ping_send(ObPingTarget *t) { t->sent = event_get_server_time(); - /*ob_debug("PINGing client 0x%x at %lu\n", t->client->window, t->sent);*/ + ob_debug("PINGing client %s at %lu\n", t->client->title, t->sent); PROP_MSG_TO(t->client->window, t->client->window, wm_protocols, prop_atoms.net_wm_ping, t->sent, t->client->window, 0, 0, NoEventMask); -- cgit v1.2.3 From 053558dc5ffa7f561d06cfd43926e19b4d4da422 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 22:53:05 -0500 Subject: add a comment --- openbox/client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'openbox') diff --git a/openbox/client.c b/openbox/client.c index 2f8f58a9..c90c39bf 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -3230,11 +3230,11 @@ void client_close(ObClient *self) XKillClient(ob_display, self->window); else if (self->not_responding) client_kill(self); - else { + else + /* request the client to close with WM_DELETE_WINDOW */ PROP_MSG_TO(self->window, self->window, wm_protocols, prop_atoms.wm_delete_window, event_curtime, 0, 0, 0, NoEventMask); - } } void client_kill(ObClient *self) -- cgit v1.2.3 From 7bd8e97fbb751f2a4b9b4feea140a703540bc4e3 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 22:56:24 -0500 Subject: rework and comment out some debugging prints --- openbox/ping.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'openbox') diff --git a/openbox/ping.c b/openbox/ping.c index 531b8938..daabbfb5 100644 --- a/openbox/ping.c +++ b/openbox/ping.c @@ -87,8 +87,8 @@ void ping_got_pong(Time timestamp) for (it = ping_targets; it != NULL; it = g_slist_next(it)) { t = it->data; if (t->sent == timestamp) { - ob_debug("Got PONG with timestamp %lu for %s\n", timestamp, - t->client->title); + /*ob_debug("PONG: '%s' (timestamp %lu)\n", t->client->title, + t->sent);*/ if (t->waiting > PING_TIMEOUT_WARN) { /* we had notified that they weren't responding, so now we need to notify that they are again */ @@ -107,6 +107,7 @@ void ping_got_pong(Time timestamp) static void ping_send(ObPingTarget *t) { t->sent = event_get_server_time(); + /*ob_debug("PING: '%s' (timestamp %lu)\n", t->client->title, t->sent);*/ ob_debug("PINGing client %s at %lu\n", t->client->title, t->sent); PROP_MSG_TO(t->client->window, t->client->window, wm_protocols, prop_atoms.net_wm_ping, t->sent, t->client->window, 0, 0, -- cgit v1.2.3 From cfc8101333535e3336eff5e929839c5262231db6 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Jan 2008 23:28:30 -0500 Subject: don't let repeating timers, with a very fast timer in the queue, cause the main loop to run the timers forever --- openbox/mainloop.c | 23 ++++++++++++++++++++--- openbox/ping.c | 2 +- 2 files changed, 21 insertions(+), 4 deletions(-) (limited to 'openbox') diff --git a/openbox/mainloop.c b/openbox/mainloop.c index c1ede830..30ecbebd 100644 --- a/openbox/mainloop.c +++ b/openbox/mainloop.c @@ -104,6 +104,10 @@ struct _ObMainLoopTimer GTimeVal last; /* When this timer will next trigger */ GTimeVal timeout; + + /* Only allow a timer's function to fire once per run through the list, + so that it doesn't get locked in there forever */ + gboolean fired; }; struct _ObMainLoopSignalHandlerType @@ -558,11 +562,11 @@ void ob_main_loop_timeout_remove_data(ObMainLoop *loop, GSourceFunc handler, { GSList *it; + ob_debug("removing data 0x%x\n", data); for (it = loop->timers; it; it = g_slist_next(it)) { ObMainLoopTimer *t = it->data; - if (t->func == handler && - (t->equal ? t->equal(t->data, data) : (t->data == data))) - { + if (t->func == handler && t->equal(t->data, data)) { + ob_debug("found data 0x%x\n", data); t->del_me = TRUE; if (cancel_dest) t->destroy = NULL; @@ -599,6 +603,12 @@ static void timer_dispatch(ObMainLoop *loop, GTimeVal **wait) g_get_current_time(&loop->now); + /* do this first, cuz the list can get reordered */ + for (it = loop->timers; it; it = g_slist_next(it)) { + ObMainLoopTimer *curr = it->data; + curr->fired = FALSE; + } + for (it = loop->timers; it; it = next) { ObMainLoopTimer *curr; @@ -623,6 +633,12 @@ static void timer_dispatch(ObMainLoop *loop, GTimeVal **wait) if (timecompare(&NEAREST_TIMEOUT(loop), &loop->now) < 0) break; + /* don't let it fire again this time around. otherwise, if the first + timer in the queue becomes ready, we'll loop on the later ones + forever if they repeat */ + if (curr->fired) + continue; + /* we set the last fired time to delay msec after the previous firing, then re-insert. timers maintain their order and may trigger more than once if they've waited more than one delay's worth of time. @@ -638,6 +654,7 @@ static void timer_dispatch(ObMainLoop *loop, GTimeVal **wait) g_free(curr); } + curr->fired = TRUE; fired = TRUE; } diff --git a/openbox/ping.c b/openbox/ping.c index daabbfb5..d159805d 100644 --- a/openbox/ping.c +++ b/openbox/ping.c @@ -64,7 +64,7 @@ void ping_start(struct _ObClient *client, ObPingEventHandler h) ping_send(t); ping_targets = g_slist_prepend(ping_targets, t); ob_main_loop_timeout_add(ob_main_loop, PING_TIMEOUT, ping_timeout, - t, NULL, NULL); + t, g_direct_equal, NULL); if (!active) { active = TRUE; -- cgit v1.2.3 From ba6dcc15f8893b1d72f185e838c3d34c62f335b4 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 16 Jan 2008 00:24:56 -0500 Subject: add the new pid and ping atoms to the NET_SUPPORTED list --- openbox/screen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'openbox') diff --git a/openbox/screen.c b/openbox/screen.c index 379a12d8..b88562fe 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -289,6 +289,8 @@ gboolean screen_annex(void) supported[i++] = prop_atoms.net_wm_sync_request; supported[i++] = prop_atoms.net_wm_sync_request_counter; #endif + supported[i++] = prop_atoms.net_wm_pid; + supported[i++] = prop_atoms.net_wm_ping; supported[i++] = prop_atoms.kde_wm_change_state; supported[i++] = prop_atoms.kde_net_wm_frame_strut; -- cgit v1.2.3 From ff78d28f8bcdbbdd42fe9501ee81185f67a4166a Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 16 Jan 2008 00:54:17 -0500 Subject: fix timers so that they work when theres lots of repeating timers in the queue.. --- openbox/mainloop.c | 29 ++++++++--------------------- openbox/ping.c | 1 - 2 files changed, 8 insertions(+), 22 deletions(-) (limited to 'openbox') diff --git a/openbox/mainloop.c b/openbox/mainloop.c index 30ecbebd..825d3f4f 100644 --- a/openbox/mainloop.c +++ b/openbox/mainloop.c @@ -504,10 +504,8 @@ void ob_main_loop_fd_remove(ObMainLoop *loop, static glong timecompare(GTimeVal *a, GTimeVal *b) { glong r; - - if ((r = b->tv_sec - a->tv_sec)) return r; - return b->tv_usec - a->tv_usec; - + if ((r = a->tv_sec - b->tv_sec)) return r; + return a->tv_usec - b->tv_usec; } static void insert_timer(ObMainLoop *loop, ObMainLoopTimer *ins) @@ -515,7 +513,7 @@ static void insert_timer(ObMainLoop *loop, ObMainLoopTimer *ins) GSList *it; for (it = loop->timers; it; it = g_slist_next(it)) { ObMainLoopTimer *t = it->data; - if (timecompare(&ins->timeout, &t->timeout) >= 0) { + if (timecompare(&ins->timeout, &t->timeout) <= 0) { loop->timers = g_slist_insert_before(loop->timers, it, ins); break; } @@ -562,11 +560,9 @@ void ob_main_loop_timeout_remove_data(ObMainLoop *loop, GSourceFunc handler, { GSList *it; - ob_debug("removing data 0x%x\n", data); for (it = loop->timers; it; it = g_slist_next(it)) { ObMainLoopTimer *t = it->data; if (t->func == handler && t->equal(t->data, data)) { - ob_debug("found data 0x%x\n", data); t->del_me = TRUE; if (cancel_dest) t->destroy = NULL; @@ -603,12 +599,6 @@ static void timer_dispatch(ObMainLoop *loop, GTimeVal **wait) g_get_current_time(&loop->now); - /* do this first, cuz the list can get reordered */ - for (it = loop->timers; it; it = g_slist_next(it)) { - ObMainLoopTimer *curr = it->data; - curr->fired = FALSE; - } - for (it = loop->timers; it; it = next) { ObMainLoopTimer *curr; @@ -630,15 +620,9 @@ static void timer_dispatch(ObMainLoop *loop, GTimeVal **wait) /* the queue is sorted, so if this timer shouldn't fire, none are ready */ - if (timecompare(&NEAREST_TIMEOUT(loop), &loop->now) < 0) + if (timecompare(&NEAREST_TIMEOUT(loop), &loop->now) > 0) break; - /* don't let it fire again this time around. otherwise, if the first - timer in the queue becomes ready, we'll loop on the later ones - forever if they repeat */ - if (curr->fired) - continue; - /* we set the last fired time to delay msec after the previous firing, then re-insert. timers maintain their order and may trigger more than once if they've waited more than one delay's worth of time. @@ -654,7 +638,10 @@ static void timer_dispatch(ObMainLoop *loop, GTimeVal **wait) g_free(curr); } - curr->fired = TRUE; + /* the timer queue has been shuffled, start from the beginning + (which is the next one to fire) */ + next = loop->timers; + fired = TRUE; } diff --git a/openbox/ping.c b/openbox/ping.c index d159805d..19922b25 100644 --- a/openbox/ping.c +++ b/openbox/ping.c @@ -108,7 +108,6 @@ static void ping_send(ObPingTarget *t) { t->sent = event_get_server_time(); /*ob_debug("PING: '%s' (timestamp %lu)\n", t->client->title, t->sent);*/ - ob_debug("PINGing client %s at %lu\n", t->client->title, t->sent); PROP_MSG_TO(t->client->window, t->client->window, wm_protocols, prop_atoms.net_wm_ping, t->sent, t->client->window, 0, 0, NoEventMask); -- cgit v1.2.3 From cafba3acf3ef5b34be867a155ec05b35e82384e9 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 16 Jan 2008 01:16:47 -0500 Subject: active = FALSE when not active ! --- openbox/ping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'openbox') diff --git a/openbox/ping.c b/openbox/ping.c index 19922b25..d4217fdd 100644 --- a/openbox/ping.c +++ b/openbox/ping.c @@ -148,7 +148,7 @@ static void ping_end(ObClient *client, gpointer data) /* stop listening if we're not waiting for any more pings */ if (!ping_targets) { - active = TRUE; + active = FALSE; client_remove_destroy_notify(ping_end); } } -- cgit v1.2.3 From 0be98fee4743c795b06aa23881b82eff5bab3ef6 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Wed, 16 Jan 2008 15:25:08 +0100 Subject: Various fixes for sparse warnings. Define void functions with (void), not (). Add missing includes. Some functions were declared static but defined non-static. Some variables that should be file static were file global but not used in any other file. prop.h defined a new prop_atoms in each file that included it instead of declaring it extern. --- openbox/actions.c | 2 +- openbox/client.c | 15 ++++++++++----- openbox/client_list_combined_menu.c | 2 +- openbox/event.c | 5 +++-- openbox/focus_cycle_indicator.c | 3 ++- openbox/keyboard.c | 2 +- openbox/mainloop.c | 4 ++-- openbox/ping.c | 1 + openbox/prop.h | 2 +- openbox/resist.c | 1 + openbox/screen.c | 6 +++--- openbox/stacking.c | 4 ++-- openbox/translate.c | 1 + openbox/xerror.c | 1 + 14 files changed, 30 insertions(+), 19 deletions(-) (limited to 'openbox') diff --git a/openbox/actions.c b/openbox/actions.c index 75d4af05..0c84489a 100644 --- a/openbox/actions.c +++ b/openbox/actions.c @@ -124,7 +124,7 @@ static void actions_definition_unref(ObActionsDefinition *def) } } -ObActionsAct* actions_build_act_from_string(const gchar *name) +static ObActionsAct* actions_build_act_from_string(const gchar *name) { GSList *it; ObActionsDefinition *def = NULL; diff --git a/openbox/client.c b/openbox/client.c index c90c39bf..6a6ec2bd 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -24,6 +24,7 @@ #include "xerror.h" #include "screen.h" #include "moveresize.h" +#include "ping.h" #include "place.h" #include "prop.h" #include "extensions.h" @@ -79,6 +80,10 @@ static void client_get_state(ObClient *self); static void client_get_shaped(ObClient *self); static void client_get_mwm_hints(ObClient *self); static void client_get_colormap(ObClient *self); +static void client_set_desktop_recursive(ObClient *self, + guint target, + gboolean donthide, + gboolean dontraise); static void client_change_allowed_actions(ObClient *self); static void client_change_state(ObClient *self); static void client_change_wm_state(ObClient *self); @@ -1551,7 +1556,7 @@ void client_update_sync_request_counter(ObClient *self) } #endif -void client_get_colormap(ObClient *self) +static void client_get_colormap(ObClient *self) { XWindowAttributes wa; @@ -3276,10 +3281,10 @@ void client_hilite(ObClient *self, gboolean hilite) } } -void client_set_desktop_recursive(ObClient *self, - guint target, - gboolean donthide, - gboolean dontraise) +static void client_set_desktop_recursive(ObClient *self, + guint target, + gboolean donthide, + gboolean dontraise) { guint old; GSList *it; diff --git a/openbox/client_list_combined_menu.c b/openbox/client_list_combined_menu.c index 194c927e..f7fc36b8 100644 --- a/openbox/client_list_combined_menu.c +++ b/openbox/client_list_combined_menu.c @@ -30,7 +30,7 @@ #define MENU_NAME "client-list-combined-menu" -ObMenu *combined_menu; +static ObMenu *combined_menu; #define SEPARATOR -1 #define ADD_DESKTOP -2 diff --git a/openbox/event.c b/openbox/event.c index 5d85eaeb..f4ebfa47 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -43,6 +43,7 @@ #include "stacking.h" #include "extensions.h" #include "translate.h" +#include "ping.h" #include #include @@ -102,8 +103,8 @@ static void focus_delay_client_dest(ObClient *client, gpointer data); Time event_curtime = CurrentTime; Time event_last_user_time = CurrentTime; /*! The serial of the current X event */ -gulong event_curserial; +static gulong event_curserial; static gboolean focus_left_screen = FALSE; /*! A list of ObSerialRanges which are to be ignored for mouse enter events */ static GSList *ignore_serials = NULL; @@ -1917,7 +1918,7 @@ static void focus_delay_client_dest(ObClient *client, gpointer data) client, FALSE); } -void event_halt_focus_delay() +void event_halt_focus_delay(void) { /* ignore all enter events up till the event which caused this to occur */ if (event_curserial) event_ignore_enter_range(1, event_curserial); diff --git a/openbox/focus_cycle_indicator.c b/openbox/focus_cycle_indicator.c index 340abec6..0aa65a75 100644 --- a/openbox/focus_cycle_indicator.c +++ b/openbox/focus_cycle_indicator.c @@ -18,6 +18,7 @@ */ #include "focus_cycle.h" +#include "focus_cycle_indicator.h" #include "client.h" #include "openbox.h" #include "frame.h" @@ -29,7 +30,7 @@ #define FOCUS_INDICATOR_WIDTH 6 -struct +static struct { InternalWindow top; InternalWindow left; diff --git a/openbox/keyboard.c b/openbox/keyboard.c index eddda577..4c570dfb 100644 --- a/openbox/keyboard.c +++ b/openbox/keyboard.c @@ -265,7 +265,7 @@ void keyboard_event(ObClient *client, const XEvent *e) } } -void keyboard_rebind() +void keyboard_rebind(void) { tree_rebind(keyboard_firstnode); grab_keys(TRUE); diff --git a/openbox/mainloop.c b/openbox/mainloop.c index 825d3f4f..f78f5b12 100644 --- a/openbox/mainloop.c +++ b/openbox/mainloop.c @@ -39,13 +39,13 @@ typedef struct _ObMainLoopFdHandlerType ObMainLoopFdHandlerType; static GSList *all_loops; /* signals are global to all loops */ -struct { +static struct { guint installed; /* a ref count */ struct sigaction oldact; } all_signals[NUM_SIGNALS]; /* a set of all possible signals */ -sigset_t all_signals_set; +static sigset_t all_signals_set; /* signals which cause a core dump, these can't be used for callbacks */ static gint core_signals[] = diff --git a/openbox/ping.c b/openbox/ping.c index d4217fdd..eed09479 100644 --- a/openbox/ping.c +++ b/openbox/ping.c @@ -21,6 +21,7 @@ #include "client.h" #include "prop.h" #include "event.h" +#include "debug.h" #include "mainloop.h" #include "openbox.h" diff --git a/openbox/prop.h b/openbox/prop.h index 92884144..5ca70470 100644 --- a/openbox/prop.h +++ b/openbox/prop.h @@ -196,7 +196,7 @@ typedef struct Atoms { Atom ob_theme; Atom ob_control; } Atoms; -Atoms prop_atoms; +extern Atoms prop_atoms; void prop_startup(); diff --git a/openbox/resist.c b/openbox/resist.c index 62c2b293..f21eb8e6 100644 --- a/openbox/resist.c +++ b/openbox/resist.c @@ -23,6 +23,7 @@ #include "screen.h" #include "dock.h" #include "config.h" +#include "resist.h" #include "parser/parse.h" #include diff --git a/openbox/screen.c b/openbox/screen.c index b88562fe..e008ffe5 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -60,15 +60,15 @@ guint screen_num_desktops; guint screen_num_monitors; guint screen_desktop; guint screen_last_desktop = 1; -guint screen_old_desktop; -gboolean screen_desktop_timeout = TRUE; -Size screen_physical_size; gboolean screen_showing_desktop; ObDesktopLayout screen_desktop_layout; gchar **screen_desktop_names; Window screen_support_win; Time screen_desktop_user_time = CurrentTime; +static Size screen_physical_size; +static guint screen_old_desktop; +static gboolean screen_desktop_timeout = TRUE; /*! An array of desktops, holding array of areas per monitor */ static Rect *monitor_area = NULL; /*! An array of desktops, holding an array of struts */ diff --git a/openbox/stacking.c b/openbox/stacking.c index 34ab0588..b18c02af 100644 --- a/openbox/stacking.c +++ b/openbox/stacking.c @@ -31,7 +31,7 @@ GList *stacking_list = NULL; /*! When true, stacking changes will not be reflected on the screen. This is to freeze the on-screen stacking order while a window is being temporarily raised during focus cycling */ -gboolean pause_changes = FALSE; +static gboolean pause_changes = FALSE; void stacking_set_list(void) { @@ -134,7 +134,7 @@ void stacking_temp_raise(ObWindow *window) pause_changes = TRUE; } -void stacking_restore() +void stacking_restore(void) { Window *win; GList *it; diff --git a/openbox/translate.c b/openbox/translate.c index b2ae7d67..c697679d 100644 --- a/openbox/translate.c +++ b/openbox/translate.c @@ -20,6 +20,7 @@ #include "openbox.h" #include "mouse.h" #include "modkeys.h" +#include "translate.h" #include "gettext.h" #include #include diff --git a/openbox/xerror.c b/openbox/xerror.c index 6e884607..2657b8ea 100644 --- a/openbox/xerror.c +++ b/openbox/xerror.c @@ -20,6 +20,7 @@ #include "openbox.h" #include "gettext.h" #include "debug.h" +#include "xerror.h" #include #include -- cgit v1.2.3 From 9e18dbe0eed4f23909a0566dbc8b55b1bac470b8 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 16 Jan 2008 10:31:12 -0500 Subject: friendly check for the timer's delay being > 0 --- openbox/mainloop.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'openbox') diff --git a/openbox/mainloop.c b/openbox/mainloop.c index f78f5b12..b2921207 100644 --- a/openbox/mainloop.c +++ b/openbox/mainloop.c @@ -530,6 +530,9 @@ void ob_main_loop_timeout_add(ObMainLoop *loop, GDestroyNotify notify) { ObMainLoopTimer *t = g_new(ObMainLoopTimer, 1); + + g_assert(microseconds > 0); /* if it's 0 it'll cause an infinite loop */ + t->delay = microseconds; t->func = handler; t->data = data; -- cgit v1.2.3 From 2ee4251092a70af6a7c1826aaef01506dfcbf556 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 16 Jan 2008 18:16:49 -0500 Subject: use unique IDs for pings rather than a timestamp. avoids duplicates. --- openbox/ping.c | 19 +++++++++---------- openbox/ping.h | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'openbox') diff --git a/openbox/ping.c b/openbox/ping.c index eed09479..92fb8630 100644 --- a/openbox/ping.c +++ b/openbox/ping.c @@ -29,12 +29,13 @@ typedef struct _ObPingTarget { ObClient *client; ObPingEventHandler h; - Time sent; + guint32 id; gint waiting; } ObPingTarget; static GSList *ping_targets = NULL; static gboolean active = FALSE; +static guint32 ping_next_id = 1; #define PING_TIMEOUT (G_USEC_PER_SEC * 3) /*! Warn the user after this many PING_TIMEOUT intervals */ @@ -79,7 +80,7 @@ void ping_stop(struct _ObClient *c) ping_end(c, NULL); } -void ping_got_pong(Time timestamp) +void ping_got_pong(guint32 id) { GSList *it; ObPingTarget *t; @@ -87,9 +88,8 @@ void ping_got_pong(Time timestamp) /* make sure we're not already pinging it */ for (it = ping_targets; it != NULL; it = g_slist_next(it)) { t = it->data; - if (t->sent == timestamp) { - /*ob_debug("PONG: '%s' (timestamp %lu)\n", t->client->title, - t->sent);*/ + if (t->id == id) { + /*g_print("-PONG: '%s' (id %u)\n", t->client->title, t->id);*/ if (t->waiting > PING_TIMEOUT_WARN) { /* we had notified that they weren't responding, so now we need to notify that they are again */ @@ -101,16 +101,15 @@ void ping_got_pong(Time timestamp) } if (it == NULL) - ob_debug("Got PONG with timestamp %lu but not waiting for one\n", - timestamp); + ob_debug("Got PONG with id %u but not waiting for one\n", id); } static void ping_send(ObPingTarget *t) { - t->sent = event_get_server_time(); - /*ob_debug("PING: '%s' (timestamp %lu)\n", t->client->title, t->sent);*/ + t->id = ping_next_id++; + /*g_print("+PING: '%s' (id %u)\n", t->client->title, t->id);*/ PROP_MSG_TO(t->client->window, t->client->window, wm_protocols, - prop_atoms.net_wm_ping, t->sent, t->client->window, 0, 0, + prop_atoms.net_wm_ping, t->id, t->client->window, 0, 0, NoEventMask); } diff --git a/openbox/ping.h b/openbox/ping.h index 0b6dfead..9f5c157b 100644 --- a/openbox/ping.h +++ b/openbox/ping.h @@ -36,6 +36,6 @@ typedef void (*ObPingEventHandler) (struct _ObClient *c, gboolean dead); void ping_start(struct _ObClient *c, ObPingEventHandler h); void ping_stop(struct _ObClient *c); -void ping_got_pong(Time timestamp); +void ping_got_pong(guint32 id); #endif -- cgit v1.2.3 From 299687110d478a4928932f72031c345b27a01840 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 16 Jan 2008 18:44:22 -0500 Subject: use hash tables in ping.[ch] instead of a list. we're pinging every window, not just windows youre trying to close, so don't use datastructures that suck with lots of windows.. --- openbox/event.c | 2 +- openbox/openbox.c | 3 ++ openbox/ping.c | 119 +++++++++++++++++++++++++++++------------------------- openbox/ping.h | 3 ++ 4 files changed, 70 insertions(+), 57 deletions(-) (limited to 'openbox') diff --git a/openbox/event.c b/openbox/event.c index f4ebfa47..025f1188 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -769,7 +769,7 @@ static void event_handle_root(XEvent *e) else if (e->xclient.data.l[0] == 3) ob_exit(0); } else if (msgtype == prop_atoms.wm_protocols) { - if (e->xclient.data.l[0] == prop_atoms.net_wm_ping) + if ((Atom)e->xclient.data.l[0] == prop_atoms.net_wm_ping) ping_got_pong(e->xclient.data.l[1]); } break; diff --git a/openbox/openbox.c b/openbox/openbox.c index 30a26609..48f31f91 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -43,6 +43,7 @@ #include "grab.h" #include "group.h" #include "config.h" +#include "ping.h" #include "mainloop.h" #include "gettext.h" #include "parser/parse.h" @@ -301,6 +302,7 @@ gint main(gint argc, gchar **argv) screen_startup(reconfigure); grab_startup(reconfigure); group_startup(reconfigure); + ping_startup(reconfigure); client_startup(reconfigure); dock_startup(reconfigure); moveresize_startup(reconfigure); @@ -360,6 +362,7 @@ gint main(gint argc, gchar **argv) moveresize_shutdown(reconfigure); dock_shutdown(reconfigure); client_shutdown(reconfigure); + ping_shutdown(reconfigure); group_shutdown(reconfigure); grab_shutdown(reconfigure); screen_shutdown(reconfigure); diff --git a/openbox/ping.c b/openbox/ping.c index 92fb8630..065cb60a 100644 --- a/openbox/ping.c +++ b/openbox/ping.c @@ -33,46 +33,59 @@ typedef struct _ObPingTarget gint waiting; } ObPingTarget; -static GSList *ping_targets = NULL; -static gboolean active = FALSE; -static guint32 ping_next_id = 1; +static GHashTable *ping_targets = NULL; +static GHashTable *ping_ids = NULL; +static guint32 ping_next_id = 1; #define PING_TIMEOUT (G_USEC_PER_SEC * 3) /*! Warn the user after this many PING_TIMEOUT intervals */ #define PING_TIMEOUT_WARN 3 -static void ping_send(ObPingTarget *t); -static void ping_end(ObClient *client, gpointer data); +static void ping_send(ObPingTarget *t); +static void ping_end(ObClient *client, gpointer data); static gboolean ping_timeout(gpointer data); +void ping_startup(gboolean reconfigure) +{ + if (reconfigure) return; + + ping_targets = g_hash_table_new(g_direct_hash, g_int_equal); + ping_ids = g_hash_table_new(g_direct_hash, g_int_equal); + + /* listen for clients to disappear */ + client_add_destroy_notify(ping_end, NULL); +} + +void ping_shutdown(gboolean reconfigure) +{ + if (reconfigure) return; + + g_hash_table_unref(ping_targets); + g_hash_table_unref(ping_ids); + + client_remove_destroy_notify(ping_end); +} + void ping_start(struct _ObClient *client, ObPingEventHandler h) { - GSList *it; ObPingTarget *t; g_assert(client->ping == TRUE); /* make sure we're not already pinging it */ - for (it = ping_targets; it != NULL; it = g_slist_next(it)) { - t = it->data; - if (t->client == client) return; - } + g_assert(g_hash_table_lookup(ping_targets, &client) == NULL); - t = g_new(ObPingTarget, 1); + t = g_new0(ObPingTarget, 1); t->client = client; t->h = h; - t->waiting = 1; /* first wait for a reply */ - ping_send(t); - ping_targets = g_slist_prepend(ping_targets, t); + g_hash_table_insert(ping_targets, &t->client, t); + ob_main_loop_timeout_add(ob_main_loop, PING_TIMEOUT, ping_timeout, t, g_direct_equal, NULL); - - if (!active) { - active = TRUE; - /* listen for the client to disappear */ - client_add_destroy_notify(ping_end, NULL); - } + /* act like we just timed out immediately, to start the pinging process + now instead of after the first delay */ + ping_timeout(t); } void ping_stop(struct _ObClient *c) @@ -82,31 +95,35 @@ void ping_stop(struct _ObClient *c) void ping_got_pong(guint32 id) { - GSList *it; ObPingTarget *t; - /* make sure we're not already pinging it */ - for (it = ping_targets; it != NULL; it = g_slist_next(it)) { - t = it->data; - if (t->id == id) { - /*g_print("-PONG: '%s' (id %u)\n", t->client->title, t->id);*/ - if (t->waiting > PING_TIMEOUT_WARN) { - /* we had notified that they weren't responding, so now we - need to notify that they are again */ - t->h(t->client, FALSE); - } - t->waiting = 0; /* not waiting for a reply anymore */ - break; + if ((t = g_hash_table_lookup(ping_ids, &id))) { + /*g_print("-PONG: '%s' (id %u)\n", t->client->title, t->id);*/ + if (t->waiting > PING_TIMEOUT_WARN) { + /* we had notified that they weren't responding, so now we + need to notify that they are again */ + t->h(t->client, FALSE); } + t->waiting = 0; /* not waiting for a reply anymore */ } - - if (it == NULL) + else ob_debug("Got PONG with id %u but not waiting for one\n", id); } static void ping_send(ObPingTarget *t) { - t->id = ping_next_id++; + /* t->id is 0 when it hasn't been assigned an id ever yet. + we can reuse ids when t->waiting == 0, because we won't be getting a + pong for that id in the future again. that way for apps that aren't + timing out we don't need to remove/add them from/to the hash table */ + if (t->id == 0 || t->waiting > 0) { + /* pick an id, and reinsert in the hash table with the new id */ + if (t->id) g_hash_table_remove(ping_ids, &t->id); + t->id = ping_next_id; + if (++ping_next_id == 0) ++ping_next_id; /* skip 0 on wraparound */ + g_hash_table_insert(ping_ids, &t->id, t); + } + /*g_print("+PING: '%s' (id %u)\n", t->client->title, t->id);*/ PROP_MSG_TO(t->client->window, t->client->window, wm_protocols, prop_atoms.net_wm_ping, t->id, t->client->window, 0, 0, @@ -117,11 +134,9 @@ static gboolean ping_timeout(gpointer data) { ObPingTarget *t = data; - if (t->waiting == 0) { /* got a reply already */ - /* send another ping to make sure it's still alive */ - ping_send(t); - } + ping_send(t); + /* if the client hasn't been responding then do something about it */ if (t->waiting == PING_TIMEOUT_WARN) t->h(t->client, TRUE); /* notify that the client isn't responding */ @@ -132,23 +147,15 @@ static gboolean ping_timeout(gpointer data) static void ping_end(ObClient *client, gpointer data) { - GSList *it; ObPingTarget *t; - for (it = ping_targets; it != NULL; it = g_slist_next(it)) { - t = it->data; - if (t->client == client) { - ping_targets = g_slist_remove_link(ping_targets, it); - ob_main_loop_timeout_remove_data(ob_main_loop, ping_timeout, t, - FALSE); - g_free(t); - break; - } - } + t = g_hash_table_lookup(ping_targets, &client); + g_assert(t); + + g_hash_table_remove(ping_targets, &t->client); + g_hash_table_remove(ping_ids, &t->id); + + ob_main_loop_timeout_remove_data(ob_main_loop, ping_timeout, t, FALSE); - /* stop listening if we're not waiting for any more pings */ - if (!ping_targets) { - active = FALSE; - client_remove_destroy_notify(ping_end); - } + g_free(t); } diff --git a/openbox/ping.h b/openbox/ping.h index 9f5c157b..1333ea0f 100644 --- a/openbox/ping.h +++ b/openbox/ping.h @@ -33,6 +33,9 @@ struct _ObClient; */ typedef void (*ObPingEventHandler) (struct _ObClient *c, gboolean dead); +void ping_startup(gboolean reconfigure); +void ping_shutdown(gboolean reconfigure); + void ping_start(struct _ObClient *c, ObPingEventHandler h); void ping_stop(struct _ObClient *c); -- cgit v1.2.3 From 7630f660350bc39d0535a5aeb1da69ba25baf26b Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 16 Jan 2008 18:53:15 -0500 Subject: only 1 hash table is needed in ping.c --- openbox/ping.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'openbox') diff --git a/openbox/ping.c b/openbox/ping.c index 065cb60a..16f95adb 100644 --- a/openbox/ping.c +++ b/openbox/ping.c @@ -33,7 +33,6 @@ typedef struct _ObPingTarget gint waiting; } ObPingTarget; -static GHashTable *ping_targets = NULL; static GHashTable *ping_ids = NULL; static guint32 ping_next_id = 1; @@ -44,12 +43,12 @@ static guint32 ping_next_id = 1; static void ping_send(ObPingTarget *t); static void ping_end(ObClient *client, gpointer data); static gboolean ping_timeout(gpointer data); +static gboolean find_client(gpointer key, gpointer value, gpointer client); void ping_startup(gboolean reconfigure) { if (reconfigure) return; - ping_targets = g_hash_table_new(g_direct_hash, g_int_equal); ping_ids = g_hash_table_new(g_direct_hash, g_int_equal); /* listen for clients to disappear */ @@ -60,7 +59,6 @@ void ping_shutdown(gboolean reconfigure) { if (reconfigure) return; - g_hash_table_unref(ping_targets); g_hash_table_unref(ping_ids); client_remove_destroy_notify(ping_end); @@ -70,17 +68,14 @@ void ping_start(struct _ObClient *client, ObPingEventHandler h) { ObPingTarget *t; - g_assert(client->ping == TRUE); + g_assert(g_hash_table_find(ping_ids, find_client, client) == NULL); - /* make sure we're not already pinging it */ - g_assert(g_hash_table_lookup(ping_targets, &client) == NULL); + g_assert(client->ping == TRUE); t = g_new0(ObPingTarget, 1); t->client = client; t->h = h; - g_hash_table_insert(ping_targets, &t->client, t); - ob_main_loop_timeout_add(ob_main_loop, PING_TIMEOUT, ping_timeout, t, g_direct_equal, NULL); /* act like we just timed out immediately, to start the pinging process @@ -110,6 +105,12 @@ void ping_got_pong(guint32 id) ob_debug("Got PONG with id %u but not waiting for one\n", id); } +static gboolean find_client(gpointer key, gpointer value, gpointer client) +{ + ObPingTarget *t = value; + return t->client == client; +} + static void ping_send(ObPingTarget *t) { /* t->id is 0 when it hasn't been assigned an id ever yet. @@ -149,10 +150,9 @@ static void ping_end(ObClient *client, gpointer data) { ObPingTarget *t; - t = g_hash_table_lookup(ping_targets, &client); - g_assert(t); + t = g_hash_table_find(ping_ids, find_client, client); + g_assert (t != NULL); - g_hash_table_remove(ping_targets, &t->client); g_hash_table_remove(ping_ids, &t->id); ob_main_loop_timeout_remove_data(ob_main_loop, ping_timeout, t, FALSE); -- cgit v1.2.3 From cccc57fdb04b2e5602254f1eb623acc95f9a032e Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 16 Jan 2008 19:21:42 -0500 Subject: make the ping hash tables work correctly. don't need to stop pinging, it will automatically. and not all windows get pings, even tho we get notified that they are being destroyed --- openbox/client.c | 9 ++++----- openbox/ping.c | 25 +++++++++++++++---------- 2 files changed, 19 insertions(+), 15 deletions(-) (limited to 'openbox') diff --git a/openbox/client.c b/openbox/client.c index 6a6ec2bd..63245a3c 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -609,7 +609,10 @@ void client_manage(Window window) /* watch for when the application stops responding. only do this for normal windows, i.e. windows which have titlebars and close buttons - and things like that */ + and things like that. + we don't need to stop pinging on unmanage, because it will be handled + automatically by the destroy callback! + */ if (self->ping && client_normal(self)) ping_start(self, client_ping_event); @@ -694,10 +697,6 @@ void client_unmanage(ObClient *self) /* remove the window from our save set */ XChangeSaveSet(ob_display, self->window, SetModeDelete); - /* stop pinging the window */ - if (self->ping && client_normal(self)) - ping_stop(self); - /* update the focus lists */ focus_order_remove(self); if (client_focused(self)) { diff --git a/openbox/ping.c b/openbox/ping.c index 16f95adb..37b5d30c 100644 --- a/openbox/ping.c +++ b/openbox/ping.c @@ -49,7 +49,7 @@ void ping_startup(gboolean reconfigure) { if (reconfigure) return; - ping_ids = g_hash_table_new(g_direct_hash, g_int_equal); + ping_ids = g_hash_table_new(g_int_hash, g_int_equal); /* listen for clients to disappear */ client_add_destroy_notify(ping_end, NULL); @@ -60,6 +60,7 @@ void ping_shutdown(gboolean reconfigure) if (reconfigure) return; g_hash_table_unref(ping_ids); + ping_ids = NULL; client_remove_destroy_notify(ping_end); } @@ -68,6 +69,7 @@ void ping_start(struct _ObClient *client, ObPingEventHandler h) { ObPingTarget *t; + /* make sure we're not already pinging the client */ g_assert(g_hash_table_find(ping_ids, find_client, client) == NULL); g_assert(client->ping == TRUE); @@ -79,8 +81,12 @@ void ping_start(struct _ObClient *client, ObPingEventHandler h) ob_main_loop_timeout_add(ob_main_loop, PING_TIMEOUT, ping_timeout, t, g_direct_equal, NULL); /* act like we just timed out immediately, to start the pinging process - now instead of after the first delay */ + now instead of after the first delay. this makes sure the client + ends up in the ping_ids hash table now. */ ping_timeout(t); + + /* make sure we can remove the client later */ + g_assert(g_hash_table_find(ping_ids, find_client, client) != NULL); } void ping_stop(struct _ObClient *c) @@ -93,7 +99,7 @@ void ping_got_pong(guint32 id) ObPingTarget *t; if ((t = g_hash_table_lookup(ping_ids, &id))) { - /*g_print("-PONG: '%s' (id %u)\n", t->client->title, t->id);*/ + /*ob_debug("-PONG: '%s' (id %u)\n", t->client->title, t->id);*/ if (t->waiting > PING_TIMEOUT_WARN) { /* we had notified that they weren't responding, so now we need to notify that they are again */ @@ -125,7 +131,7 @@ static void ping_send(ObPingTarget *t) g_hash_table_insert(ping_ids, &t->id, t); } - /*g_print("+PING: '%s' (id %u)\n", t->client->title, t->id);*/ + /*ob_debug("+PING: '%s' (id %u)\n", t->client->title, t->id);*/ PROP_MSG_TO(t->client->window, t->client->window, wm_protocols, prop_atoms.net_wm_ping, t->id, t->client->window, 0, 0, NoEventMask); @@ -150,12 +156,11 @@ static void ping_end(ObClient *client, gpointer data) { ObPingTarget *t; - t = g_hash_table_find(ping_ids, find_client, client); - g_assert (t != NULL); - - g_hash_table_remove(ping_ids, &t->id); + if ((t = g_hash_table_find(ping_ids, find_client, client))) { + g_hash_table_remove(ping_ids, &t->id); - ob_main_loop_timeout_remove_data(ob_main_loop, ping_timeout, t, FALSE); + ob_main_loop_timeout_remove_data(ob_main_loop, ping_timeout, t, FALSE); - g_free(t); + g_free(t); + } } -- cgit v1.2.3 From d3c1117fb4c0916c1d28b6bf91288a68c9712d53 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Wed, 16 Jan 2008 15:58:24 +0100 Subject: Remove leftover config_four_corners from config.c. --- openbox/config.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'openbox') diff --git a/openbox/config.c b/openbox/config.c index c094732e..867dfb51 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -61,7 +61,6 @@ guint config_screen_firstdesk; guint config_desktop_popup_time; gboolean config_resize_redraw; -gboolean config_resize_four_corners; gint config_resize_popup_show; ObResizePopupPos config_resize_popup_pos; GravityPoint config_resize_popup_fixed; @@ -916,7 +915,6 @@ void config_startup(ObParseInst *i) parse_register(i, "desktops", parse_desktops, NULL); config_resize_redraw = TRUE; - config_resize_four_corners = FALSE; config_resize_popup_show = 1; /* nonpixel increments */ config_resize_popup_pos = OB_RESIZE_POS_CENTER; GRAVITY_COORD_SET(config_resize_popup_fixed.x, 0, FALSE, FALSE); -- cgit v1.2.3