X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=064d68512572390f96db8fd68250b4f85f9245fb;hb=ad8a7e2e025cd6eba8f7b8b29f85cb9e81b808b5;hp=9cbbaf6191260ec723b4061ef92ca241066e1aa0;hpb=01a35904fec67a7f92a0eb7f19457e79ca3d0988;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 9cbbaf61..064d6851 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -274,6 +274,9 @@ void client_manage(Window window) /* get all the stuff off the window */ client_get_all(self, TRUE); + ob_debug("Window type: %d\n", self->type); + ob_debug("Window group: 0x%x\n", self->group?self->group->leader:0); + /* specify that if we exit, the window should not be destroyed and should be reparented back to root automatically */ XChangeSaveSet(ob_display, window, SetModeInsert); @@ -320,7 +323,7 @@ void client_manage(Window window) client_search_focus_tree_full(self)) && /* this checks for focus=false for the window */ (!settings || settings->focus != 0) && - focus_valid_target(self, FALSE, TRUE, FALSE, FALSE)) + focus_valid_target(self, FALSE, FALSE, TRUE, FALSE, FALSE)) { activate = TRUE; } @@ -3874,24 +3877,14 @@ ObClient *client_search_transient(ObClient *self, ObClient *search) return NULL; } -#define WANT_EDGE(cur, c) \ - if (cur == c) \ - continue; \ - if (c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL && \ - cur->desktop != screen_desktop) \ - continue; \ - if (cur->iconic) \ - continue; - -void client_find_move_directional(ObClient *self, ObDirection dir, - gint *x, gint *y) +void client_find_edge_directional(ObClient *self, ObDirection dir, + gint my_head, gint my_size, + gint my_edge_start, gint my_edge_size, + gint *dest, gboolean *near_edge) { - gint dest, edge, my_edge_start, my_edge_size, my_pos; GList *it; Rect *a, *mon; - - *x = self->frame->area.x; - *y = self->frame->area.y; + gint edge; a = screen_area(self->desktop, SCREEN_AREA_ALL_MONITORS, &self->frame->area); @@ -3900,58 +3893,51 @@ void client_find_move_directional(ObClient *self, ObDirection dir, switch(dir) { case OB_DIRECTION_NORTH: - case OB_DIRECTION_SOUTH: - my_edge_start = RECT_LEFT(self->frame->area); - 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); + if (my_head >= RECT_TOP(*mon)) + edge = RECT_TOP(*mon) - 1; else - edge = RECT_TOP(*a); + edge = RECT_TOP(*a) - 1; break; case OB_DIRECTION_SOUTH: - if (RECT_BOTTOM(self->frame->area) < RECT_BOTTOM(*mon)) - edge = RECT_BOTTOM(*mon) - self->frame->area.height; + if (my_head <= RECT_BOTTOM(*mon)) + edge = RECT_BOTTOM(*mon) + 1; else - edge = RECT_BOTTOM(*a) - self->frame->area.height; + edge = RECT_BOTTOM(*a) + 1; break; case OB_DIRECTION_EAST: - if (RECT_RIGHT(self->frame->area) < RECT_RIGHT(*mon)) - edge = RECT_RIGHT(*mon) - self->frame->area.width; + if (my_head <= RECT_RIGHT(*mon)) + edge = RECT_RIGHT(*mon) + 1; else - edge = RECT_RIGHT(*a) - self->frame->area.width; + edge = RECT_RIGHT(*a) + 1; break; case OB_DIRECTION_WEST: - if (RECT_LEFT(self->frame->area) > RECT_LEFT(*mon)) - edge = RECT_LEFT(*mon); + if (my_head >= RECT_LEFT(*mon)) + edge = RECT_LEFT(*mon) - 1; else - edge = RECT_LEFT(*a); + edge = RECT_LEFT(*a) - 1; break; default: g_assert_not_reached(); } /* 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; gint edge_start, edge_size, head, tail; 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) { case OB_DIRECTION_NORTH: @@ -3975,14 +3961,20 @@ void client_find_move_directional(ObClient *self, ObDirection dir, switch(dir) { case OB_DIRECTION_NORTH: + head = RECT_BOTTOM(cur->frame->area); + tail = RECT_TOP(cur->frame->area); + break; case OB_DIRECTION_SOUTH: - head = RECT_TOP(cur->frame->area) - self->frame->area.height; - tail = RECT_BOTTOM(cur->frame->area) + 1; + head = RECT_TOP(cur->frame->area); + tail = RECT_BOTTOM(cur->frame->area); break; case OB_DIRECTION_EAST: + head = RECT_LEFT(cur->frame->area); + tail = RECT_RIGHT(cur->frame->area); + break; case OB_DIRECTION_WEST: - head = RECT_LEFT(cur->frame->area) - self->frame->area.width; - tail = RECT_RIGHT(cur->frame->area) + 1; + head = RECT_RIGHT(cur->frame->area); + tail = RECT_LEFT(cur->frame->area); break; default: g_assert_not_reached(); @@ -3991,53 +3983,189 @@ void client_find_move_directional(ObClient *self, ObDirection dir, switch(dir) { case OB_DIRECTION_NORTH: case OB_DIRECTION_WEST: - if (my_pos <= head) + if (my_head <= head + 1) skip_head = TRUE; - if (my_pos <= tail) + if (my_head + my_size - 1 <= tail + 1) skip_tail = TRUE; - if (head < edge) + if (head < *dest) skip_head = TRUE; - if (tail < edge) + if (tail - my_size < *dest) skip_tail = TRUE; break; case OB_DIRECTION_SOUTH: case OB_DIRECTION_EAST: - if (my_pos >= head) + if (my_head >= head - 1) skip_head = TRUE; - if (my_pos >= tail) + if (my_head - my_size + 1 >= tail - 1) skip_tail = TRUE; - if (head > edge) + if (head > *dest) skip_head = TRUE; - if (tail > edge) + if (tail + my_size > *dest) skip_tail = TRUE; break; default: g_assert_not_reached(); } - if (!skip_head) - dest = head; - else if (!skip_tail) - dest = tail; + ob_debug("my head %d size %d\n", my_head, my_size); + ob_debug("head %d tail %d deest %d\n", head, tail, *dest); + if (!skip_head) { + 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, + gint *x, gint *y) +{ + 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; + case OB_DIRECTION_WEST: + head = RECT_LEFT(self->frame->area); + 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: - *y = dest; + 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; - case OB_DIRECTION_WEST: + default: + g_assert_not_reached(); + } + + client_find_edge_directional(self, dir, head, size, + e_start, e_size, &e, &near); + *x = self->frame->area.x; + *y = self->frame->area.y; + switch (dir) { case OB_DIRECTION_EAST: - *x = dest; + 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); +} - g_free(a); - g_free(mon); +void client_find_resize_directional(ObClient *self, ObDirection side, + gboolean grow, + gint *x, gint *y, gint *w, gint *h) +{ + gint head, size; + gint e, e_start, e_size, delta; + gboolean near; + ObDirection dir; + switch (side) { + case OB_DIRECTION_EAST: + head = RECT_RIGHT(self->frame->area) + (self->size_inc.width - 1); + size = self->frame->area.width; + e_start = RECT_TOP(self->frame->area); + e_size = self->frame->area.height; + dir = grow ? OB_DIRECTION_EAST : OB_DIRECTION_WEST; + break; + case OB_DIRECTION_WEST: + head = RECT_LEFT(self->frame->area) - (self->size_inc.width - 1); + size = self->frame->area.width; + e_start = RECT_TOP(self->frame->area); + e_size = self->frame->area.height; + dir = grow ? OB_DIRECTION_WEST : OB_DIRECTION_EAST; + break; + case OB_DIRECTION_NORTH: + head = RECT_TOP(self->frame->area) - (self->size_inc.height - 1); + size = self->frame->area.height; + e_start = RECT_LEFT(self->frame->area); + e_size = self->frame->area.width; + dir = grow ? OB_DIRECTION_NORTH : OB_DIRECTION_SOUTH; + break; + case OB_DIRECTION_SOUTH: + head = RECT_BOTTOM(self->frame->area) + (self->size_inc.height - 1); + size = self->frame->area.height; + e_start = RECT_LEFT(self->frame->area); + e_size = self->frame->area.width; + dir = grow ? OB_DIRECTION_SOUTH : OB_DIRECTION_NORTH; + break; + default: + g_assert_not_reached(); + } + + client_find_edge_directional(self, dir, head, size, + e_start, e_size, &e, &near); + *x = self->frame->area.x; + *y = self->frame->area.y; + *w = self->frame->area.width; + *h = self->frame->area.height; + switch (side) { + case OB_DIRECTION_EAST: + if (near) --e; + delta = e - RECT_RIGHT(self->frame->area); + *w += delta; + break; + case OB_DIRECTION_WEST: + if (near) ++e; + delta = RECT_LEFT(self->frame->area) - e; + *x -= delta; + *w += delta; + break; + case OB_DIRECTION_NORTH: + if (near) ++e; + delta = RECT_TOP(self->frame->area) - e; + *y -= delta; + *h += delta; + break; + case OB_DIRECTION_SOUTH: + if (near) --e; + delta = e - RECT_BOTTOM(self->frame->area); + *h += delta; + break; + default: + g_assert_not_reached(); + } frame_frame_gravity(self->frame, x, y); + *w -= self->frame->size.left + self->frame->size.right; + *h -= self->frame->size.top + self->frame->size.bottom; } ObClient* client_under_pointer()