small bugfix to the directional focus code.
add the client_directional_edge_search function.
This commit is contained in:
parent
a9ce3ba266
commit
c1f0f7c40f
2 changed files with 196 additions and 1 deletions
194
openbox/client.c
194
openbox/client.c
|
@ -2624,7 +2624,8 @@ ObClient *client_find_directional(ObClient *c, ObDirection dir)
|
||||||
his_cy = (cur->frame->area.y - my_cy)
|
his_cy = (cur->frame->area.y - my_cy)
|
||||||
+ cur->frame->area.height / 2;
|
+ 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;
|
int tx;
|
||||||
/* Rotate the diagonals 45 degrees counterclockwise.
|
/* Rotate the diagonals 45 degrees counterclockwise.
|
||||||
* To do this, multiply the matrix /+h +h\ with the
|
* 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);
|
PROP_GETS(self->group->leader, sm_client_id, locale, &id);
|
||||||
return 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;
|
||||||
|
}
|
||||||
|
|
|
@ -460,6 +460,9 @@ ObClient *client_search_transient(ObClient *self, ObClient *search);
|
||||||
/*! Return the "closest" client in the given direction */
|
/*! Return the "closest" client in the given direction */
|
||||||
ObClient *client_find_directional(ObClient *c, ObDirection dir);
|
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.
|
/*! Set a client window to be above/below other clients.
|
||||||
@layer < 0 indicates the client should be placed below other clients.<br>
|
@layer < 0 indicates the client should be placed below other clients.<br>
|
||||||
= 0 indicates the client should be placed with other clients.<br>
|
= 0 indicates the client should be placed with other clients.<br>
|
||||||
|
|
Loading…
Reference in a new issue