move to edge works and the code can be used for resize now too, yay

This commit is contained in:
Dana Jansens 2007-07-06 04:08:30 +00:00
parent da5a4da2bc
commit e0e1b7a5cb
3 changed files with 123 additions and 72 deletions

View file

@ -2,6 +2,7 @@
#include "openbox/misc.h" #include "openbox/misc.h"
#include "openbox/client.h" #include "openbox/client.h"
#include "openbox/frame.h" #include "openbox/frame.h"
#include "openbox/geom.h"
#include <glib.h> #include <glib.h>
typedef struct { typedef struct {

View file

@ -3874,24 +3874,14 @@ ObClient *client_search_transient(ObClient *self, ObClient *search)
return NULL; return NULL;
} }
#define WANT_EDGE(cur, c) \ void client_find_edge_directional(ObClient *self, ObDirection dir,
if (cur == c) \ gint my_head, gint my_size,
continue; \ gint my_edge_start, gint my_edge_size,
if (c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL && \ gint *dest, gboolean *near_edge)
cur->desktop != screen_desktop) \
continue; \
if (cur->iconic) \
continue;
void client_find_move_directional(ObClient *self, ObDirection dir,
gint *x, gint *y)
{ {
gint dest, edge, my_edge_start, my_edge_size, my_pos;
GList *it; GList *it;
Rect *a, *mon; Rect *a, *mon;
gint edge;
*x = self->frame->area.x;
*y = self->frame->area.y;
a = screen_area(self->desktop, SCREEN_AREA_ALL_MONITORS, a = screen_area(self->desktop, SCREEN_AREA_ALL_MONITORS,
&self->frame->area); &self->frame->area);
@ -3900,58 +3890,51 @@ void client_find_move_directional(ObClient *self, ObDirection dir,
switch(dir) { switch(dir) {
case OB_DIRECTION_NORTH: case OB_DIRECTION_NORTH:
case OB_DIRECTION_SOUTH: if (my_head >= RECT_TOP(*mon))
my_edge_start = RECT_LEFT(self->frame->area); edge = RECT_TOP(*mon) - 1;
my_edge_size = self->frame->area.width;
my_pos = RECT_TOP(self->frame->area);
break;
case OB_DIRECTION_EAST:
case OB_DIRECTION_WEST:
my_edge_start = RECT_TOP(self->frame->area);
my_edge_size = self->frame->area.height;
my_pos = RECT_LEFT(self->frame->area);
break;
default:
g_assert_not_reached();
}
switch(dir) {
case OB_DIRECTION_NORTH:
if (RECT_TOP(self->frame->area) > RECT_TOP(*mon))
edge = RECT_TOP(*mon);
else else
edge = RECT_TOP(*a); edge = RECT_TOP(*a) - 1;
break; break;
case OB_DIRECTION_SOUTH: case OB_DIRECTION_SOUTH:
if (RECT_BOTTOM(self->frame->area) < RECT_BOTTOM(*mon)) if (my_head <= RECT_BOTTOM(*mon))
edge = RECT_BOTTOM(*mon) - self->frame->area.height; edge = RECT_BOTTOM(*mon) + 1;
else else
edge = RECT_BOTTOM(*a) - self->frame->area.height; edge = RECT_BOTTOM(*a) + 1;
break; break;
case OB_DIRECTION_EAST: case OB_DIRECTION_EAST:
if (RECT_RIGHT(self->frame->area) < RECT_RIGHT(*mon)) if (my_head <= RECT_RIGHT(*mon))
edge = RECT_RIGHT(*mon) - self->frame->area.width; edge = RECT_RIGHT(*mon) + 1;
else else
edge = RECT_RIGHT(*a) - self->frame->area.width; edge = RECT_RIGHT(*a) + 1;
break; break;
case OB_DIRECTION_WEST: case OB_DIRECTION_WEST:
if (RECT_LEFT(self->frame->area) > RECT_LEFT(*mon)) if (my_head >= RECT_LEFT(*mon))
edge = RECT_LEFT(*mon); edge = RECT_LEFT(*mon) - 1;
else else
edge = RECT_LEFT(*a); edge = RECT_LEFT(*a) - 1;
break; break;
default: default:
g_assert_not_reached(); g_assert_not_reached();
} }
/* default to the far edge, then narrow it down */ /* default to the far edge, then narrow it down */
dest = edge; *dest = edge;
*near_edge = TRUE;
for(it = client_list; it && dest != my_pos; it = g_list_next(it)) { for(it = client_list; it; it = g_list_next(it)) {
ObClient *cur = it->data; ObClient *cur = it->data;
gint edge_start, edge_size, head, tail; gint edge_start, edge_size, head, tail;
gboolean skip_head = FALSE, skip_tail = FALSE; gboolean skip_head = FALSE, skip_tail = FALSE;
WANT_EDGE(cur, self); /* skip windows to not bump into */ /* skip windows to not bump into */
if (cur == self)
continue;
if (cur->iconic)
continue;
if (self->desktop != cur->desktop && cur->desktop != DESKTOP_ALL &&
cur->desktop != screen_desktop)
continue;
ob_debug("trying window %s\n", cur->title);
switch(dir) { switch(dir) {
case OB_DIRECTION_NORTH: case OB_DIRECTION_NORTH:
@ -3975,14 +3958,20 @@ void client_find_move_directional(ObClient *self, ObDirection dir,
switch(dir) { switch(dir) {
case OB_DIRECTION_NORTH: case OB_DIRECTION_NORTH:
head = RECT_BOTTOM(cur->frame->area);
tail = RECT_TOP(cur->frame->area);
break;
case OB_DIRECTION_SOUTH: case OB_DIRECTION_SOUTH:
head = RECT_TOP(cur->frame->area) - self->frame->area.height; head = RECT_TOP(cur->frame->area);
tail = RECT_BOTTOM(cur->frame->area) + 1; tail = RECT_BOTTOM(cur->frame->area);
break; break;
case OB_DIRECTION_EAST: case OB_DIRECTION_EAST:
head = RECT_LEFT(cur->frame->area);
tail = RECT_RIGHT(cur->frame->area);
break;
case OB_DIRECTION_WEST: case OB_DIRECTION_WEST:
head = RECT_LEFT(cur->frame->area) - self->frame->area.width; head = RECT_RIGHT(cur->frame->area);
tail = RECT_RIGHT(cur->frame->area) + 1; tail = RECT_LEFT(cur->frame->area);
break; break;
default: default:
g_assert_not_reached(); g_assert_not_reached();
@ -3991,52 +3980,109 @@ void client_find_move_directional(ObClient *self, ObDirection dir,
switch(dir) { switch(dir) {
case OB_DIRECTION_NORTH: case OB_DIRECTION_NORTH:
case OB_DIRECTION_WEST: case OB_DIRECTION_WEST:
if (my_pos <= head) if (my_head <= head + 1)
skip_head = TRUE; skip_head = TRUE;
if (my_pos <= tail) if (my_head + my_size - 1 <= tail + 1)
skip_tail = TRUE; skip_tail = TRUE;
if (head < edge) if (head < *dest)
skip_head = TRUE; skip_head = TRUE;
if (tail < edge) if (tail - my_size < *dest)
skip_tail = TRUE; skip_tail = TRUE;
break; break;
case OB_DIRECTION_SOUTH: case OB_DIRECTION_SOUTH:
case OB_DIRECTION_EAST: case OB_DIRECTION_EAST:
if (my_pos >= head) if (my_head >= head - 1)
skip_head = TRUE; skip_head = TRUE;
if (my_pos >= tail) if (my_head - my_size + 1 >= tail - 1)
skip_tail = TRUE; skip_tail = TRUE;
if (head > edge) if (head > *dest)
skip_head = TRUE; skip_head = TRUE;
if (tail > edge) if (tail + my_size > *dest)
skip_tail = TRUE; skip_tail = TRUE;
break; break;
default: default:
g_assert_not_reached(); g_assert_not_reached();
} }
if (!skip_head) ob_debug("my head %d size %d\n", my_head, my_size);
dest = head; ob_debug("head %d tail %d deest %d\n", head, tail, *dest);
else if (!skip_tail) if (!skip_head) {
dest = tail; ob_debug("using near edge %d\n", head);
*dest = head;
*near_edge = TRUE;
}
else if (!skip_tail) {
ob_debug("using far edge %d\n", tail);
*dest = tail;
*near_edge = FALSE;
}
} }
}
switch(dir) { void client_find_move_directional(ObClient *self, ObDirection dir,
case OB_DIRECTION_NORTH: gint *x, gint *y)
case OB_DIRECTION_SOUTH: {
*y = dest; gint head, size;
gint e, e_start, e_size;
gboolean near;
switch (dir) {
case OB_DIRECTION_EAST:
head = RECT_RIGHT(self->frame->area);
size = self->frame->area.width;
e_start = RECT_TOP(self->frame->area);
e_size = self->frame->area.height;
break; break;
case OB_DIRECTION_WEST: case OB_DIRECTION_WEST:
case OB_DIRECTION_EAST: head = RECT_LEFT(self->frame->area);
*x = dest; size = self->frame->area.width;
e_start = RECT_TOP(self->frame->area);
e_size = self->frame->area.height;
break;
case OB_DIRECTION_NORTH:
head = RECT_TOP(self->frame->area);
size = self->frame->area.height;
e_start = RECT_LEFT(self->frame->area);
e_size = self->frame->area.width;
break;
case OB_DIRECTION_SOUTH:
head = RECT_BOTTOM(self->frame->area);
size = self->frame->area.height;
e_start = RECT_LEFT(self->frame->area);
e_size = self->frame->area.width;
break; break;
default: default:
g_assert_not_reached(); g_assert_not_reached();
} }
g_free(a); client_find_edge_directional(self, dir, head, size,
g_free(mon); e_start, e_size, &e, &near);
*x = self->frame->area.x;
*y = self->frame->area.y;
switch (dir) {
case OB_DIRECTION_EAST:
if (near) e -= self->frame->area.width;
else e++;
*x = e;
break;
case OB_DIRECTION_WEST:
if (near) e++;
else e -= self->frame->area.width;
*x = e;
break;
case OB_DIRECTION_NORTH:
if (near) e++;
else e -= self->frame->area.height;
*y = e;
break;
case OB_DIRECTION_SOUTH:
if (near) e -= self->frame->area.height;
else e++;
*y = e;
break;
default:
g_assert_not_reached();
}
frame_frame_gravity(self->frame, x, y); frame_frame_gravity(self->frame, x, y);
} }

View file

@ -457,6 +457,10 @@ void client_move_onscreen(ObClient *self, gboolean rude);
/*! dir is either North, South, East or West. It can't be, for example, /*! dir is either North, South, East or West. It can't be, for example,
Northwest */ Northwest */
void client_find_edge_directional(ObClient *self, ObDirection dir,
gint my_head, gint my_tail,
gint my_edge_start, gint my_edge_size,
gint *dest, gboolean *near_edge);
void client_find_move_directional(ObClient *self, ObDirection dir, void client_find_move_directional(ObClient *self, ObDirection dir,
gint *x, gint *y); gint *x, gint *y);