small bugfix to the directional focus code.

add the client_directional_edge_search function.
This commit is contained in:
Dana Jansens 2003-08-12 08:25:04 +00:00
parent a9ce3ba266
commit c1f0f7c40f
2 changed files with 196 additions and 1 deletions

View file

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

View file

@ -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.<br>
= 0 indicates the client should be placed with other clients.<br>