From: Dana Jansens Date: Tue, 12 Aug 2003 08:25:04 +0000 (+0000) Subject: small bugfix to the directional focus code. X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=c1f0f7c40fbbc33157d59b5e3db58a0801af5008;p=chaz%2Fopenbox small bugfix to the directional focus code. add the client_directional_edge_search function. --- diff --git a/openbox/client.c b/openbox/client.c index b5e2a3cf..1c3152c8 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -2624,7 +2624,8 @@ ObClient *client_find_directional(ObClient *c, ObDirection dir) his_cy = (cur->frame->area.y - my_cy) + cur->frame->area.height / 2; - if(dir > 3) { + if(dir == OB_DIRECTION_NORTHEAST || dir == OB_DIRECTION_SOUTHEAST || + dir == OB_DIRECTION_SOUTHWEST || dir == OB_DIRECTION_NORTHWEST) { int tx; /* Rotate the diagonals 45 degrees counterclockwise. * To do this, multiply the matrix /+h +h\ with the @@ -2752,3 +2753,194 @@ gchar* client_get_sm_client_id(ObClient *self) PROP_GETS(self->group->leader, sm_client_id, locale, &id); return id; } + +/* finds the nearest edge in the given direction from the current client + * note to self: the edge is the -frame- edge (the actual one), not the + * client edge. + */ +int client_directional_edge_search(ObClient *c, ObDirection dir) +{ + int dest; + int my_edge_start, my_edge_end, my_offset; + GList *it; + Rect *a; + + if(!client_list) + return -1; + + a = screen_area(c->desktop); + + switch(dir) { + case OB_DIRECTION_NORTH: + my_edge_start = c->frame->area.x; + my_edge_end = c->frame->area.x + c->frame->area.width; + my_offset = c->frame->area.y; + + dest = a->y; /* default: top of screen */ + + for(it = g_list_first(client_list); it; it = it->next) { + int his_edge_start, his_edge_end, his_offset; + ObClient *cur = it->data; + + if(cur == c) + continue; + if(!client_normal(cur)) + continue; + if(c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL) + continue; + if(cur->iconic) + continue; + + his_edge_start = cur->frame->area.x; + his_edge_end = cur->frame->area.x + cur->frame->area.width; + his_offset = cur->frame->area.y + cur->frame->area.height; + + if(his_offset + c->size_inc.height > my_offset) + continue; + + if(his_offset < dest) + continue; + + if(his_edge_start >= my_edge_start && + his_edge_start <= my_edge_end) + dest = his_offset; + + if(my_edge_start >= his_edge_start && + my_edge_start <= his_edge_end) + dest = his_offset; + + } + break; + case OB_DIRECTION_SOUTH: + my_edge_start = c->frame->area.x; + my_edge_end = c->frame->area.x + c->frame->area.width; + my_offset = c->frame->area.y + c->frame->area.height; + + dest = a->y + a->height; /* default: bottom of screen */ + + for(it = g_list_first(client_list); it; it = it->next) { + int his_edge_start, his_edge_end, his_offset; + ObClient *cur = it->data; + + if(cur == c) + continue; + if(!client_normal(cur)) + continue; + if(c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL) + continue; + if(cur->iconic) + continue; + + his_edge_start = cur->frame->area.x; + his_edge_end = cur->frame->area.x + cur->frame->area.width; + his_offset = cur->frame->area.y; + + + if(his_offset - c->size_inc.height < my_offset) + continue; + + if(his_offset > dest) + continue; + + if(his_edge_start >= my_edge_start && + his_edge_start <= my_edge_end) + dest = his_offset; + + if(my_edge_start >= his_edge_start && + my_edge_start <= his_edge_end) + dest = his_offset; + + } + break; + case OB_DIRECTION_WEST: + my_edge_start = c->frame->area.y; + my_edge_end = c->frame->area.y + c->frame->area.height; + my_offset = c->frame->area.x; + + dest = a->x; /* default: leftmost egde of screen */ + + for(it = g_list_first(client_list); it; it = it->next) { + int his_edge_start, his_edge_end, his_offset; + ObClient *cur = it->data; + + if(cur == c) + continue; + if(!client_normal(cur)) + continue; + if(c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL) + continue; + if(cur->iconic) + continue; + + his_edge_start = cur->frame->area.y; + his_edge_end = cur->frame->area.y + cur->frame->area.height; + his_offset = cur->frame->area.x + cur->frame->area.width; + + if(his_offset + c->size_inc.width > my_offset) + continue; + + if(his_offset < dest) + continue; + + if(his_edge_start >= my_edge_start && + his_edge_start <= my_edge_end) + dest = his_offset; + + if(my_edge_start >= his_edge_start && + my_edge_start <= his_edge_end) + dest = his_offset; + + + } + break; + case OB_DIRECTION_EAST: + my_edge_start = c->frame->area.y; + my_edge_end = c->frame->area.y + c->frame->area.height; + my_offset = c->frame->area.x + c->frame->area.width; + + dest = a->x + a->width; /* default: rightmost edge of screen */ + + for(it = g_list_first(client_list); it; it = it->next) { + int his_edge_start, his_edge_end, his_offset; + ObClient *cur = it->data; + + if(cur == c) + continue; + if(!client_normal(cur)) + continue; + if(c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL) + continue; + if(cur->iconic) + continue; + + his_edge_start = cur->frame->area.y; + his_edge_end = cur->frame->area.y + cur->frame->area.height; + his_offset = cur->frame->area.x; + + if(his_offset - c->size_inc.width < my_offset) + continue; + + if(his_offset > dest) + continue; + + if(his_edge_start >= my_edge_start && + his_edge_start <= my_edge_end) + dest = his_offset; + + if(my_edge_start >= his_edge_start && + my_edge_start <= his_edge_end) + dest = his_offset; + + } + break; + case OB_DIRECTION_NORTHEAST: + case OB_DIRECTION_SOUTHEAST: + case OB_DIRECTION_NORTHWEST: + case OB_DIRECTION_SOUTHWEST: + /* not implemented */ + break; + default: + g_assert_not_reached(); + } + return dest; +} diff --git a/openbox/client.h b/openbox/client.h index 954b7424..dba6786e 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -460,6 +460,9 @@ 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 */ +int client_directional_edge_search(ObClient *c, ObDirection dir); + /*! Set a client window to be above/below other clients. @layer < 0 indicates the client should be placed below other clients.
= 0 indicates the client should be placed with other clients.