all repos — openbox @ 9f11e2af6b230c168814c362bd1647c481e0330a

openbox fork - make it a bit more like ryudo

cycling between dock windows now possible with the <panels>yes</panels> option
Dana Jansens danakj@orodu.net
commit

9f11e2af6b230c168814c362bd1647c481e0330a

parent

33e017838fa6f2747f2ec217843fa7a08f6b516e

6 files changed, 154 insertions(+), 129 deletions(-)

jump to
M openbox/action.copenbox/action.c

@@ -119,6 +119,7 @@ {

(*a)->data.interdiraction.inter.any.interactive = TRUE; (*a)->data.interdiraction.direction = OB_DIRECTION_NORTH; (*a)->data.interdiraction.dialog = TRUE; + (*a)->data.interdiraction.dock_windows = FALSE; } void setup_action_directional_focus_east(ObAction **a, ObUserAction uact)

@@ -126,6 +127,7 @@ {

(*a)->data.interdiraction.inter.any.interactive = TRUE; (*a)->data.interdiraction.direction = OB_DIRECTION_EAST; (*a)->data.interdiraction.dialog = TRUE; + (*a)->data.interdiraction.dock_windows = FALSE; } void setup_action_directional_focus_south(ObAction **a, ObUserAction uact)

@@ -133,6 +135,7 @@ {

(*a)->data.interdiraction.inter.any.interactive = TRUE; (*a)->data.interdiraction.direction = OB_DIRECTION_SOUTH; (*a)->data.interdiraction.dialog = TRUE; + (*a)->data.interdiraction.dock_windows = FALSE; } void setup_action_directional_focus_west(ObAction **a, ObUserAction uact)

@@ -140,6 +143,7 @@ {

(*a)->data.interdiraction.inter.any.interactive = TRUE; (*a)->data.interdiraction.direction = OB_DIRECTION_WEST; (*a)->data.interdiraction.dialog = TRUE; + (*a)->data.interdiraction.dock_windows = FALSE; } void setup_action_directional_focus_northeast(ObAction **a, ObUserAction uact)

@@ -147,6 +151,7 @@ {

(*a)->data.interdiraction.inter.any.interactive = TRUE; (*a)->data.interdiraction.direction = OB_DIRECTION_NORTHEAST; (*a)->data.interdiraction.dialog = TRUE; + (*a)->data.interdiraction.dock_windows = FALSE; } void setup_action_directional_focus_southeast(ObAction **a, ObUserAction uact)

@@ -154,6 +159,7 @@ {

(*a)->data.interdiraction.inter.any.interactive = TRUE; (*a)->data.interdiraction.direction = OB_DIRECTION_SOUTHEAST; (*a)->data.interdiraction.dialog = TRUE; + (*a)->data.interdiraction.dock_windows = FALSE; } void setup_action_directional_focus_southwest(ObAction **a, ObUserAction uact)

@@ -161,6 +167,7 @@ {

(*a)->data.interdiraction.inter.any.interactive = TRUE; (*a)->data.interdiraction.direction = OB_DIRECTION_SOUTHWEST; (*a)->data.interdiraction.dialog = TRUE; + (*a)->data.interdiraction.dock_windows = FALSE; } void setup_action_directional_focus_northwest(ObAction **a, ObUserAction uact)

@@ -168,6 +175,7 @@ {

(*a)->data.interdiraction.inter.any.interactive = TRUE; (*a)->data.interdiraction.direction = OB_DIRECTION_NORTHWEST; (*a)->data.interdiraction.dialog = TRUE; + (*a)->data.interdiraction.dock_windows = FALSE; } void setup_action_send_to_desktop(ObAction **a, ObUserAction uact)

@@ -295,6 +303,7 @@ (*a)->data.cycle.inter.any.interactive = TRUE;

(*a)->data.cycle.linear = FALSE; (*a)->data.cycle.forward = TRUE; (*a)->data.cycle.dialog = TRUE; + (*a)->data.cycle.dock_windows = FALSE; } void setup_action_cycle_windows_previous(ObAction **a, ObUserAction uact)

@@ -303,6 +312,7 @@ (*a)->data.cycle.inter.any.interactive = TRUE;

(*a)->data.cycle.linear = FALSE; (*a)->data.cycle.forward = FALSE; (*a)->data.cycle.dialog = TRUE; + (*a)->data.cycle.dock_windows = FALSE; } void setup_action_movefromedge_north(ObAction **a, ObUserAction uact)

@@ -1003,9 +1013,13 @@ if ((n = parse_find_node("linear", node->xmlChildrenNode)))

act->data.cycle.linear = parse_bool(doc, n); if ((n = parse_find_node("dialog", node->xmlChildrenNode))) act->data.cycle.dialog = parse_bool(doc, n); + if ((n = parse_find_node("panels", node->xmlChildrenNode))) + act->data.cycle.dock_windows = parse_bool(doc, n); } else if (act->func == action_directional_focus) { if ((n = parse_find_node("dialog", node->xmlChildrenNode))) - act->data.cycle.dialog = parse_bool(doc, n); + act->data.interdiraction.dialog = parse_bool(doc, n); + if ((n = parse_find_node("panels", node->xmlChildrenNode))) + act->data.interdiraction.dock_windows = parse_bool(doc, n); } else if (act->func == action_raise || act->func == action_lower || act->func == action_raiselower ||

@@ -1647,7 +1661,9 @@ /* if using focus_delay, stop the timer now so that focus doesn't go moving

on us */ event_halt_focus_delay(); - focus_cycle(data->cycle.forward, data->cycle.linear, data->any.interactive, + focus_cycle(data->cycle.forward, + data->cycle.dock_windows, + data->cycle.linear, data->any.interactive, data->cycle.dialog, data->cycle.inter.final, data->cycle.inter.cancel); }

@@ -1659,6 +1675,7 @@ on us */

event_halt_focus_delay(); focus_directional_cycle(data->interdiraction.direction, + data->interdiraction.dock_windows, data->any.interactive, data->interdiraction.dialog, data->interdiraction.inter.final,
M openbox/action.hopenbox/action.h

@@ -61,6 +61,7 @@ struct InterDirectionalAction{

struct InteractiveAction inter; ObDirection direction; gboolean dialog; + gboolean dock_windows; }; struct DirectionalAction{

@@ -141,6 +142,7 @@ struct InteractiveAction inter;

gboolean linear; gboolean forward; gboolean dialog; + gboolean dock_windows; }; struct Stacking {
M openbox/client.copenbox/client.c

@@ -3188,107 +3188,6 @@ }

return ret; } -/* this be mostly ripped from fvwm */ -ObClient *client_find_directional(ObClient *c, ObDirection dir) -{ - gint my_cx, my_cy, his_cx, his_cy; - gint offset = 0; - gint distance = 0; - gint score, best_score; - ObClient *best_client, *cur; - GList *it; - - if(!client_list) - return NULL; - - /* first, find the centre coords of the currently focused window */ - my_cx = c->frame->area.x + c->frame->area.width / 2; - my_cy = c->frame->area.y + c->frame->area.height / 2; - - best_score = -1; - best_client = NULL; - - for(it = g_list_first(client_list); it; it = g_list_next(it)) { - cur = it->data; - - /* the currently selected window isn't interesting */ - if(cur == c) - continue; - if (!client_normal(cur)) - continue; - /* using c->desktop instead of screen_desktop doesn't work if the - * current window was omnipresent, hope this doesn't have any other - * side effects */ - if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) - continue; - if(cur->iconic) - continue; - if(!(client_focus_target(cur) == cur && - client_can_focus(cur))) - continue; - - /* find the centre coords of this window, from the - * currently focused window's point of view */ - his_cx = (cur->frame->area.x - my_cx) - + cur->frame->area.width / 2; - his_cy = (cur->frame->area.y - my_cy) - + cur->frame->area.height / 2; - - if(dir == OB_DIRECTION_NORTHEAST || dir == OB_DIRECTION_SOUTHEAST || - dir == OB_DIRECTION_SOUTHWEST || dir == OB_DIRECTION_NORTHWEST) { - gint tx; - /* Rotate the diagonals 45 degrees counterclockwise. - * To do this, multiply the matrix /+h +h\ with the - * vector (x y). \-h +h/ - * h = sqrt(0.5). We can set h := 1 since absolute - * distance doesn't matter here. */ - tx = his_cx + his_cy; - his_cy = -his_cx + his_cy; - his_cx = tx; - } - - switch(dir) { - case OB_DIRECTION_NORTH: - case OB_DIRECTION_SOUTH: - case OB_DIRECTION_NORTHEAST: - case OB_DIRECTION_SOUTHWEST: - offset = (his_cx < 0) ? -his_cx : his_cx; - distance = ((dir == OB_DIRECTION_NORTH || - dir == OB_DIRECTION_NORTHEAST) ? - -his_cy : his_cy); - break; - case OB_DIRECTION_EAST: - case OB_DIRECTION_WEST: - case OB_DIRECTION_SOUTHEAST: - case OB_DIRECTION_NORTHWEST: - offset = (his_cy < 0) ? -his_cy : his_cy; - distance = ((dir == OB_DIRECTION_WEST || - dir == OB_DIRECTION_NORTHWEST) ? - -his_cx : his_cx); - break; - } - - /* the target must be in the requested direction */ - if(distance <= 0) - continue; - - /* Calculate score for this window. The smaller the better. */ - score = distance + offset; - - /* windows more than 45 degrees off the direction are - * heavily penalized and will only be chosen if nothing - * else within a million pixels */ - if(offset > distance) - score += 1000000; - - if(best_score == -1 || score < best_score) - best_client = cur, - best_score = score; - } - - return best_client; -} - void client_set_layer(ObClient *self, gint layer) { if (layer < 0) {
M openbox/client.hopenbox/client.h

@@ -620,9 +620,6 @@ /*! Search for a transient of a client. The transient is returned if it is one,

NULL is returned if the given search is not a transient of the client. */ ObClient *client_search_transient(ObClient *self, ObClient *search); -/*! Return the "closest" client in the given direction */ -ObClient *client_find_directional(ObClient *c, ObDirection dir); - /*! Return the closest edge in the given direction */ gint client_directional_edge_search(ObClient *c, ObDirection dir, gboolean hang);
M openbox/focus.copenbox/focus.c

@@ -59,7 +59,7 @@ /* end cycling if the target disappears. CurrentTime is fine, time won't

be used */ if (focus_cycle_target == client) - focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); + focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); } static Window createWindow(Window parent, gulong mask,

@@ -168,7 +168,7 @@ /* in the middle of cycling..? kill it. CurrentTime is fine, time won't

be used. */ if (focus_cycle_target) - focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); + focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); focus_client = client;

@@ -468,23 +468,27 @@ XMapWindow(ob_display, focus_indicator.bottom.win);

} } -static gboolean valid_focus_target(ObClient *ft) +static gboolean valid_focus_target(ObClient *ft, gboolean dock_windows) { + gboolean ok = FALSE; /* we don't use client_can_focus here, because that doesn't let you focus an iconic window, but we want to be able to, so we just check if the focus flags on the window allow it, and its on the current desktop */ - if ((ft->type == OB_CLIENT_TYPE_NORMAL || - ft->type == OB_CLIENT_TYPE_DIALOG || - (!client_has_group_siblings(ft) && - (ft->type == OB_CLIENT_TYPE_TOOLBAR || - ft->type == OB_CLIENT_TYPE_MENU || - ft->type == OB_CLIENT_TYPE_UTILITY))) && - ((ft->can_focus || ft->focus_notify) && - !ft->skip_pager && - (ft->desktop == screen_desktop || ft->desktop == DESKTOP_ALL)) && - ft == client_focus_target(ft)) - return TRUE; + if (dock_windows) + ok = ft->type == OB_CLIENT_TYPE_DOCK; + else + ok = (ft->type == OB_CLIENT_TYPE_NORMAL || + ft->type == OB_CLIENT_TYPE_DIALOG || + (!client_has_group_siblings(ft) && + (ft->type == OB_CLIENT_TYPE_TOOLBAR || + ft->type == OB_CLIENT_TYPE_MENU || + ft->type == OB_CLIENT_TYPE_UTILITY))); + ok = ok && (ft->can_focus || ft->focus_notify); + ok = ok && !ft->skip_pager; + ok = ok && (ft->desktop == screen_desktop || ft->desktop == DESKTOP_ALL); + ok = ok && ft == client_focus_target(ft); + return ok; /* { GSList *it;

@@ -498,11 +502,10 @@ }

return TRUE; } */ - - return FALSE; } -void focus_cycle(gboolean forward, gboolean linear, gboolean interactive, +void focus_cycle(gboolean forward, gboolean dock_windows, + gboolean linear, gboolean interactive, gboolean dialog, gboolean done, gboolean cancel) { static ObClient *first = NULL;

@@ -546,7 +549,7 @@ it = it->prev;

if (it == NULL) it = g_list_last(list); } ft = it->data; - if (valid_focus_target(ft)) { + if (valid_focus_target(ft, dock_windows)) { if (interactive) { if (ft != focus_cycle_target) { /* prevents flicker */ focus_cycle_target = ft;

@@ -580,7 +583,112 @@

return; } -void focus_directional_cycle(ObDirection dir, gboolean interactive, +/* this be mostly ripped from fvwm */ +ObClient *focus_find_directional(ObClient *c, ObDirection dir, + gboolean dock_windows) +{ + gint my_cx, my_cy, his_cx, his_cy; + gint offset = 0; + gint distance = 0; + gint score, best_score; + ObClient *best_client, *cur; + GList *it; + + if(!client_list) + return NULL; + + /* first, find the centre coords of the currently focused window */ + my_cx = c->frame->area.x + c->frame->area.width / 2; + my_cy = c->frame->area.y + c->frame->area.height / 2; + + best_score = -1; + best_client = NULL; + + for(it = g_list_first(client_list); it; it = g_list_next(it)) { + cur = it->data; + + /* the currently selected window isn't interesting */ + if(cur == c) + continue; + if (!dock_windows && !client_normal(cur)) + continue; + if (dock_windows && cur->type != OB_CLIENT_TYPE_DOCK) + continue; + /* using c->desktop instead of screen_desktop doesn't work if the + * current window was omnipresent, hope this doesn't have any other + * side effects */ + if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) + continue; + if(cur->iconic) + continue; + if(!(client_focus_target(cur) == cur && + client_can_focus(cur))) + continue; + + /* find the centre coords of this window, from the + * currently focused window's point of view */ + his_cx = (cur->frame->area.x - my_cx) + + cur->frame->area.width / 2; + his_cy = (cur->frame->area.y - my_cy) + + cur->frame->area.height / 2; + + if(dir == OB_DIRECTION_NORTHEAST || dir == OB_DIRECTION_SOUTHEAST || + dir == OB_DIRECTION_SOUTHWEST || dir == OB_DIRECTION_NORTHWEST) { + gint tx; + /* Rotate the diagonals 45 degrees counterclockwise. + * To do this, multiply the matrix /+h +h\ with the + * vector (x y). \-h +h/ + * h = sqrt(0.5). We can set h := 1 since absolute + * distance doesn't matter here. */ + tx = his_cx + his_cy; + his_cy = -his_cx + his_cy; + his_cx = tx; + } + + switch(dir) { + case OB_DIRECTION_NORTH: + case OB_DIRECTION_SOUTH: + case OB_DIRECTION_NORTHEAST: + case OB_DIRECTION_SOUTHWEST: + offset = (his_cx < 0) ? -his_cx : his_cx; + distance = ((dir == OB_DIRECTION_NORTH || + dir == OB_DIRECTION_NORTHEAST) ? + -his_cy : his_cy); + break; + case OB_DIRECTION_EAST: + case OB_DIRECTION_WEST: + case OB_DIRECTION_SOUTHEAST: + case OB_DIRECTION_NORTHWEST: + offset = (his_cy < 0) ? -his_cy : his_cy; + distance = ((dir == OB_DIRECTION_WEST || + dir == OB_DIRECTION_NORTHWEST) ? + -his_cx : his_cx); + break; + } + + /* the target must be in the requested direction */ + if(distance <= 0) + continue; + + /* Calculate score for this window. The smaller the better. */ + score = distance + offset; + + /* windows more than 45 degrees off the direction are + * heavily penalized and will only be chosen if nothing + * else within a million pixels */ + if(offset > distance) + score += 1000000; + + if(best_score == -1 || score < best_score) + best_client = cur, + best_score = score; + } + + return best_client; +} + +void focus_directional_cycle(ObDirection dir, gboolean dock_windows, + gboolean interactive, gboolean dialog, gboolean done, gboolean cancel) { static ObClient *first = NULL;

@@ -602,12 +710,12 @@ if (!first) first = focus_client;

if (!focus_cycle_target) focus_cycle_target = focus_client; if (focus_cycle_target) - ft = client_find_directional(focus_cycle_target, dir); + ft = focus_find_directional(focus_cycle_target, dir, dock_windows); else { GList *it; for (it = focus_order; it; it = g_list_next(it)) - if (valid_focus_target(it->data)) + if (valid_focus_target(it->data, dock_windows)) ft = it->data; }
M openbox/focus.hopenbox/focus.h

@@ -52,9 +52,11 @@ /*! Call this when you need to focus something! */

void focus_fallback(gboolean allow_refocus); /*! Cycle focus amongst windows. */ -void focus_cycle(gboolean forward, gboolean linear, gboolean interactive, +void focus_cycle(gboolean forward, gboolean dock_windows, + gboolean linear, gboolean interactive, gboolean dialog, gboolean done, gboolean cancel); -void focus_directional_cycle(ObDirection dir, gboolean interactive, +void focus_directional_cycle(ObDirection dir, gboolean dock_windows, + gboolean interactive, gboolean dialog, gboolean done, gboolean cancel); void focus_cycle_draw_indicator();