X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=0392ee35e2a04e28481ac05754b12b247eb76614;hb=1c98d2e3a6c721e9b2c7ce9a4343d06e4f714261;hp=064d68512572390f96db8fd68250b4f85f9245fb;hpb=ad8a7e2e025cd6eba8f7b8b29f85cb9e81b808b5;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 064d6851..0392ee35 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -1,5 +1,5 @@ /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- - + client.c for the Openbox window manager Copyright (c) 2006 Mikael Magnusson Copyright (c) 2003-2007 Dana Jansens @@ -237,7 +237,7 @@ void client_manage(Window window) grab_server(FALSE); return; /* don't manage it */ } - + /* is the window a docking app */ if ((wmhint = XGetWMHints(ob_display, window))) { if ((wmhint->flags & StateHint) && @@ -382,7 +382,8 @@ void client_manage(Window window) */ ob_state() == OB_STATE_RUNNING && (transient || - (!(self->positioned & USPosition) && + (!((self->positioned & USPosition) || + (settings && settings->pos_given)) && client_normal(self) && !self->session))); } @@ -596,7 +597,7 @@ ObClient *client_fake_manage(Window window) frame_adjust_area(self->frame, FALSE, TRUE, TRUE); ob_debug("gave extents left %d right %d top %d bottom %d\n", - self->frame->size.left, self->frame->size.right, + self->frame->size.left, self->frame->size.right, self->frame->size.top, self->frame->size.bottom); /* free the ObAppSettings shallow copy */ @@ -983,10 +984,15 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h, for (i = 0; i < screen_num_monitors; ++i) { Rect *a; - if (!screen_physical_area_monitor_contains(i, &desired)) - continue; + if (!screen_physical_area_monitor_contains(i, &desired)) { + if (i < screen_num_monitors - 1) + continue; - a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &desired); + /* the window is not inside any monitor! so just use the first + one */ + a = screen_area(self->desktop, 0, NULL); + } else + a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &desired); /* This makes sure windows aren't entirely outside of the screen so you can't see them at all. @@ -1003,7 +1009,7 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h, if (!self->strut.left && *x + fw*9/10 - 1 < a->x) *x = a->x - fw*9/10; if (!self->strut.top && *y + fh*9/10 - 1 < a->y) - *y = a->y - fw*9/10; + *y = a->y - fh*9/10; } /* This here doesn't let windows even a pixel outside the @@ -1072,7 +1078,7 @@ static void client_get_all(ObClient *self, gboolean real) if (self->type == OB_CLIENT_TYPE_DESKTOP) self->desktop = DESKTOP_ALL; } - + #ifdef SYNC client_update_sync_request_counter(self); #endif @@ -1098,7 +1104,7 @@ static void client_get_area(ObClient *self) { XWindowAttributes wattrib; Status ret; - + ret = XGetWindowAttributes(ob_display, self->window, &wattrib); g_assert(ret != BadWindow); @@ -1119,7 +1125,7 @@ static void client_get_desktop(ObClient *self) self->desktop = screen_num_desktops - 1; else self->desktop = d; - ob_debug("client requested desktop 0x%x\n", self->desktop); + ob_debug("client requested desktop 0x%x\n", self->desktop); } else { GSList *it; gboolean first = TRUE; @@ -1166,7 +1172,7 @@ static void client_get_state(ObClient *self) { guint32 *state; guint num; - + if (PROP_GETA32(self->window, net_wm_state, atom, &state, &num)) { gulong i; for (i = 0; i < num; ++i) { @@ -1249,7 +1255,7 @@ void client_update_transient_for(ObClient *self) self->transient_for_group, trangroup, client_direct_parent(self), target); self->transient_for_group = trangroup; - + } static void client_update_transient_tree(ObClient *self, @@ -1281,88 +1287,45 @@ static void client_update_transient_tree(ObClient *self, oldgtran == newgtran && oldparent == newparent) return; - /** Remove the client from the transient tree wherever it has changed **/ - - /* If the window is becoming a direct transient for a window in its group - then any group transients which were our children and are now becoming - our parents need to stop being our children. + /** Remove the client from the transient tree **/ - Group transients can't be children of group transients already, but - we could have any number of direct parents above up, any of which could - be transient for the group, and we need to remove it from our children. - */ - if (!oldgtran && oldparent != newparent && newparent != NULL && - newgroup != NULL && newgroup == oldgroup && - client_normal(newparent)) - { - ObClient *look = client_search_top_direct_parent(newparent); - self->transients = g_slist_remove(self->transients, look); - look->parents = g_slist_remove(look->parents, self); + for (it = self->transients; it; it = next) { + next = g_slist_next(it); + c = it->data; + self->transients = g_slist_delete_link(self->transients, it); + c->parents = g_slist_remove(c->parents, self); } - - - /* If the group changed, or if we are just becoming transient for the - group, then we need to remove any old group transient windows - from our children. But if we were already transient for the group, then - other group transients are not our children. */ - if ((oldgroup != newgroup || (newgtran && oldgtran != newgtran)) && - oldgroup != NULL && !oldgtran) - { - for (it = self->transients; it; it = next) { - next = g_slist_next(it); - c = it->data; - if (c->group == oldgroup && client_normal(self)) { - self->transients = g_slist_delete_link(self->transients, it); - c->parents = g_slist_remove(c->parents, self); - } - } + for (it = self->parents; it; it = next) { + next = g_slist_next(it); + c = it->data; + self->parents = g_slist_delete_link(self->parents, it); + c->transients = g_slist_remove(c->transients, self); } - /* If we used to be transient for a group and now we are not, or we're - transient for a new group, then we need to remove ourselves from all - our ex-parents */ - if (oldgtran && (oldgroup != newgroup || oldgtran != newgtran)) - { - for (it = self->parents; it; it = next) { - next = g_slist_next(it); - c = it->data; - if (!c->transient_for_group && client_normal(c)) { - c->transients = g_slist_remove(c->transients, self); - self->parents = g_slist_delete_link(self->parents, it); - } - } - } - /* If we used to be transient for a single window and we are no longer - transient for it, then we need to remove ourself from its children */ - else if (oldparent && oldparent != newparent && - client_normal(oldparent)) - { - oldparent->transients = g_slist_remove(oldparent->transients, self); - self->parents = g_slist_remove(self->parents, oldparent); - } + /** Re-add the client to the transient tree **/ - /** Re-add the client to the transient tree wherever it has changed **/ - - /* If we're now transient for a group and we weren't transient for it - before then we need to add ourselves to all our new parents */ - if (newgtran && (oldgroup != newgroup || oldgtran != newgtran)) - { - for (it = oldgroup->members; it; it = g_slist_next(it)) { + /* If we're transient for a group then we need to add ourselves to all our + parents */ + if (newgtran) { + for (it = newgroup->members; it; it = g_slist_next(it)) { c = it->data; - if (c != self && !c->transient_for_group && client_normal(c)) + if (c != self && + !client_search_top_direct_parent(c)->transient_for_group && + client_normal(c)) { c->transients = g_slist_prepend(c->transients, self); self->parents = g_slist_prepend(self->parents, c); } } } - /* If we are now transient for a single window which we weren't before, - we need to add ourselves to its children + + /* If we are now transient for a single window we need to add ourselves to + its children WARNING: Cyclical transient ness is possible if two windows are transient for eachother. */ - else if (newparent && newparent != oldparent && + else if (newparent && /* don't make ourself its child if it is already our child */ !client_is_direct_child(self, newparent) && client_normal(newparent)) @@ -1371,9 +1334,8 @@ static void client_update_transient_tree(ObClient *self, self->parents = g_slist_prepend(self->parents, newparent); } - /* If the group changed then we need to add any new group transient - windows to our children. But if we're transient for the group, then - other group transients are not our children. + /* Add any group transient windows to our children. But if we're transient + for the group, then other group transients are not our children. WARNING: Cyclical transient-ness is possible. For e.g. if: A is transient for the group @@ -1381,7 +1343,9 @@ static void client_update_transient_tree(ObClient *self, C is transient for B A can't be transient for C or we have a cycle */ - if (oldgroup != newgroup && newgroup != NULL && !newgtran && + if (!newgtran && newgroup && + (!newparent || + !client_search_top_direct_parent(newparent)->transient_for_group) && client_normal(self)) { for (it = newgroup->members; it; it = g_slist_next(it)) { @@ -1395,6 +1359,20 @@ static void client_update_transient_tree(ObClient *self, } } } + + /** If we change our group transient-ness, our children change their + effect group transient-ness, which affects how they relate to other + group windows **/ + + for (it = self->transients; it; it = g_slist_next(it)) { + c = it->data; + if (!c->transient_for_group) + client_update_transient_tree(c, c->group, c->group, + c->transient_for_group, + c->transient_for_group, + client_direct_parent(c), + client_direct_parent(c)); + } } static void client_get_mwm_hints(ObClient *self) @@ -1423,7 +1401,7 @@ void client_get_type_and_transientness(ObClient *self) self->type = -1; self->transient = FALSE; - + if (PROP_GETA32(self->window, net_wm_window_type, atom, &val, &num)) { /* use the first value that we know about in the array */ for (i = 0; i < num; ++i) { @@ -1459,7 +1437,7 @@ void client_get_type_and_transientness(ObClient *self) if (XGetTransientForHint(ob_display, self->window, &t)) self->transient = TRUE; - + if (self->type == (ObClientType) -1) { /*the window type hint was not set, which means we either classify ourself as a normal window or a dialog, depending on if we are a @@ -1498,7 +1476,7 @@ void client_update_protocols(ObClient *self) notified whenever we want it to receive focus */ self->focus_notify = TRUE; #ifdef SYNC - else if (proto[i] == prop_atoms.net_wm_sync_request) + else if (proto[i] == prop_atoms.net_wm_sync_request) /* if this protocol is requested, then resizing the window will be synchronized between the frame and the client */ @@ -1578,13 +1556,13 @@ void client_update_normal_hints(ObClient *self) if (size.flags & PMinSize) SIZE_SET(self->min_size, size.min_width, size.min_height); - + if (size.flags & PMaxSize) SIZE_SET(self->max_size, size.max_width, size.max_height); - + if (size.flags & PBaseSize) SIZE_SET(self->base_size, size.base_width, size.base_height); - + if (size.flags & PResizeInc && size.width_inc && size.height_inc) SIZE_SET(self->size_inc, size.width_inc, size.height_inc); @@ -1818,7 +1796,7 @@ void client_update_wmhints(ObClient *self) /* assume a window takes input if it doesnt specify */ self->can_focus = TRUE; - + if ((hints = XGetWMHints(ob_display, self->window)) != NULL) { gboolean ur; @@ -1905,17 +1883,17 @@ void client_update_title(ObClient *self) gchar *visible = NULL; g_free(self->title); - + /* try netwm */ if (!PROP_GETS(self->window, net_wm_name, utf8, &data)) { /* try old x stuff */ if (!(PROP_GETS(self->window, wm_name, locale, &data) || PROP_GETS(self->window, wm_name, utf8, &data))) { if (self->transient) { - /* - GNOME alert windows are not given titles: - http://developer.gnome.org/projects/gup/hig/draft_hig_new/windows-alert.html - */ + /* + GNOME alert windows are not given titles: + http://developer.gnome.org/projects/gup/hig/draft_hig_new/windows-alert.html + */ data = g_strdup(""); } else data = g_strdup("Unnamed Window"); @@ -2033,7 +2011,7 @@ void client_update_icons(ObClient *self) } self->icons = g_new(ObClientIcon, self->nicons); - + /* store the icons */ i = 0; for (j = 0; j < self->nicons; ++j) { @@ -2090,7 +2068,7 @@ void client_update_icons(ObClient *self) or removes it entirely, it's not very likely it is going to set one right away afterwards - if it has parents, then one of them will have an icon already + if it has parents, then one of them will have an icon already */ if (self->nicons == 0 && !self->parents) { RrPixel32 *icon = ob_rr_theme->def_win_icon; @@ -2464,7 +2442,7 @@ gboolean client_should_show(ObClient *self) return FALSE; if (self->desktop == screen_desktop || self->desktop == DESKTOP_ALL) return TRUE; - + return FALSE; } @@ -2608,7 +2586,7 @@ static void client_apply_startup_state(ObClient *self, client_shade(self, TRUE); if (demands_attention) client_hilite(self, TRUE); - + if (max_vert && max_horz) client_maximize(self, TRUE, 0); else if (max_vert) @@ -2810,7 +2788,7 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, /* you cannot resize to nothing */ if (basew + *w < 1) *w = 1 - basew; if (baseh + *h < 1) *h = 1 - baseh; - + /* save the logical size */ *logicalw = incw > 1 ? *w : *w + basew; *logicalh = inch > 1 ? *h : *h + baseh; @@ -3125,7 +3103,7 @@ void client_iconify(ObClient *self, gboolean iconic, gboolean curdesk, void client_maximize(ObClient *self, gboolean max, gint dir) { gint x, y, w, h; - + g_assert(dir == 0 || dir == 1 || dir == 2); if (!(self->functions & OB_CLIENT_FUNC_MAXIMIZE)) return; /* can't */ @@ -3213,7 +3191,7 @@ void client_close(ObClient *self) close, we just kill it */ if (!self->delete_window) client_kill(self); - + /* XXX: itd be cool to do timeouts and shit here for killing the client's process off @@ -3315,7 +3293,7 @@ ObClient *client_search_modal_child(ObClient *self) { GSList *it; ObClient *ret; - + for (it = self->transients; it; it = g_slist_next(it)) { ObClient *c = it->data; if ((ret = client_search_modal_child(c))) return ret; @@ -3326,7 +3304,7 @@ ObClient *client_search_modal_child(ObClient *self) gboolean client_validate(ObClient *self) { - XEvent e; + XEvent e; XSync(ob_display, FALSE); /* get all events on the server */ @@ -3342,7 +3320,7 @@ gboolean client_validate(ObClient *self) void client_set_wm_state(ObClient *self, glong state) { if (state == self->wmstate) return; /* no change */ - + switch (state) { case IconicState: client_iconify(self, TRUE, TRUE, FALSE); @@ -3371,11 +3349,11 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2) action == prop_atoms.net_wm_state_remove || action == prop_atoms.net_wm_state_toggle)) /* an invalid action was passed to the client message, ignore it */ - return; + return; for (i = 0; i < 2; ++i) { Atom state = i == 0 ? data1 : data2; - + if (!state) continue; /* if toggling, then pick whether we're adding or removing */ @@ -3422,7 +3400,7 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2) action = undecorated ? prop_atoms.net_wm_state_remove : prop_atoms.net_wm_state_add; } - + if (action == prop_atoms.net_wm_state_add) { if (state == prop_atoms.net_wm_state_modal) { modal = TRUE; @@ -3731,7 +3709,7 @@ static ObClientIcon* client_icon_recursive(ObClient *self, gint w, gint h) if ((parent = client_icon_recursive(c, w, h))) break; } - + return parent; } @@ -3785,7 +3763,7 @@ void client_set_layer(ObClient *self, gint layer) void client_set_undecorated(ObClient *self, gboolean undecorated) { if (self->undecorated != undecorated && - /* don't let it undecorate if the function is missing, but let + /* don't let it undecorate if the function is missing, but let it redecorate */ (self->functions & OB_CLIENT_FUNC_UNDECORATE || !undecorated)) { @@ -3805,7 +3783,7 @@ ObClient *client_direct_parent(ObClient *self) if (!self->parents) return NULL; if (self->transient_for_group) return NULL; return self->parents->data; -} +} ObClient *client_search_top_direct_parent(ObClient *self) { @@ -3820,7 +3798,7 @@ static GSList *client_search_all_top_parents_internal(ObClient *self, { GSList *ret; ObClient *p; - + /* move up the direct transient chain as far as possible */ while ((p = client_direct_parent(self)) && (!bylayer || p->layer == layer)) @@ -3877,6 +3855,96 @@ ObClient *client_search_transient(ObClient *self, ObClient *search) return NULL; } +static void detect_edge(Rect area, ObDirection dir, + gint my_head, gint my_size, + gint my_edge_start, gint my_edge_size, + gint *dest, gboolean *near_edge) +{ + gint edge_start, edge_size, head, tail; + gboolean skip_head = FALSE, skip_tail = FALSE; + + switch(dir) { + case OB_DIRECTION_NORTH: + case OB_DIRECTION_SOUTH: + edge_start = area.x; + edge_size = area.width; + break; + case OB_DIRECTION_EAST: + case OB_DIRECTION_WEST: + edge_start = area.y; + edge_size = area.height; + break; + default: + g_assert_not_reached(); + } + + /* do we collide with this window? */ + if (!RANGES_INTERSECT(my_edge_start, my_edge_size, + edge_start, edge_size)) + return; + + switch(dir) { + case OB_DIRECTION_NORTH: + head = RECT_BOTTOM(area); + tail = RECT_TOP(area); + break; + case OB_DIRECTION_SOUTH: + head = RECT_TOP(area); + tail = RECT_BOTTOM(area); + break; + case OB_DIRECTION_EAST: + head = RECT_LEFT(area); + tail = RECT_RIGHT(area); + break; + case OB_DIRECTION_WEST: + head = RECT_RIGHT(area); + tail = RECT_LEFT(area); + break; + default: + g_assert_not_reached(); + } + switch(dir) { + case OB_DIRECTION_NORTH: + case OB_DIRECTION_WEST: + if (my_head <= head + 1) + skip_head = TRUE; + if (my_head + my_size - 1 <= tail) + skip_tail = TRUE; + if (head < *dest) + skip_head = TRUE; + if (tail - my_size < *dest) + skip_tail = TRUE; + break; + case OB_DIRECTION_SOUTH: + case OB_DIRECTION_EAST: + if (my_head >= head - 1) + skip_head = TRUE; + if (my_head - my_size + 1 >= tail) + skip_tail = TRUE; + if (head > *dest) + skip_head = TRUE; + if (tail + my_size > *dest) + skip_tail = TRUE; + break; + default: + g_assert_not_reached(); + } + + 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; + } + +} + void client_find_edge_directional(ObClient *self, ObDirection dir, gint my_head, gint my_size, gint my_edge_start, gint my_edge_size, @@ -3884,6 +3952,7 @@ void client_find_edge_directional(ObClient *self, ObDirection dir, { GList *it; Rect *a, *mon; + Rect dock_area; gint edge; a = screen_area(self->desktop, SCREEN_AREA_ALL_MONITORS, @@ -3925,8 +3994,6 @@ void client_find_edge_directional(ObClient *self, ObDirection dir, 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; /* skip windows to not bump into */ if (cur == self) @@ -3939,87 +4006,12 @@ void client_find_edge_directional(ObClient *self, ObDirection dir, ob_debug("trying window %s\n", cur->title); - switch(dir) { - case OB_DIRECTION_NORTH: - case OB_DIRECTION_SOUTH: - edge_start = cur->frame->area.x; - edge_size = cur->frame->area.width; - break; - case OB_DIRECTION_EAST: - case OB_DIRECTION_WEST: - edge_start = cur->frame->area.y; - edge_size = cur->frame->area.height; - break; - default: - g_assert_not_reached(); - } - - /* do we collide with this window? */ - if (!RANGES_INTERSECT(my_edge_start, my_edge_size, - edge_start, edge_size)) - continue; - - 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); - 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_RIGHT(cur->frame->area); - tail = RECT_LEFT(cur->frame->area); - break; - default: - g_assert_not_reached(); - } - - switch(dir) { - case OB_DIRECTION_NORTH: - case OB_DIRECTION_WEST: - if (my_head <= head + 1) - skip_head = TRUE; - if (my_head + my_size - 1 <= tail + 1) - skip_tail = TRUE; - if (head < *dest) - skip_head = TRUE; - if (tail - my_size < *dest) - skip_tail = TRUE; - break; - case OB_DIRECTION_SOUTH: - case OB_DIRECTION_EAST: - if (my_head >= head - 1) - skip_head = TRUE; - if (my_head - my_size + 1 >= tail - 1) - skip_tail = TRUE; - if (head > *dest) - skip_head = TRUE; - if (tail + my_size > *dest) - skip_tail = TRUE; - break; - default: - g_assert_not_reached(); - } - - 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; - } + detect_edge(cur->frame->area, dir, my_head, my_size, my_edge_start, + my_edge_size, dest, near_edge); } + dock_get_area(&dock_area); + detect_edge(dock_area, dir, my_head, my_size, my_edge_start, + my_edge_size, dest, near_edge); } void client_find_move_directional(ObClient *self, ObDirection dir, @@ -4093,36 +4085,36 @@ void client_find_resize_directional(ObClient *self, ObDirection side, gboolean grow, gint *x, gint *y, gint *w, gint *h) { - gint head, size; + gint head; 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; + head = RECT_RIGHT(self->frame->area) + + (self->size_inc.width - 1) * (grow ? 1 : -1); 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; + head = RECT_LEFT(self->frame->area) - + (self->size_inc.width - 1) * (grow ? 1 : -1); 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; + head = RECT_TOP(self->frame->area) - + (self->size_inc.height - 1) * (grow ? 1 : -1); 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; + head = RECT_BOTTOM(self->frame->area) + + (self->size_inc.height - 1) * (grow ? 1 : -1); e_start = RECT_LEFT(self->frame->area); e_size = self->frame->area.width; dir = grow ? OB_DIRECTION_SOUTH : OB_DIRECTION_NORTH; @@ -4131,32 +4123,34 @@ void client_find_resize_directional(ObClient *self, ObDirection side, g_assert_not_reached(); } - client_find_edge_directional(self, dir, head, size, + ob_debug("head %d dir %d\n", head, dir); + client_find_edge_directional(self, dir, head, 1, e_start, e_size, &e, &near); + ob_debug("edge %d\n", e); *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; + if (grow == near) --e; delta = e - RECT_RIGHT(self->frame->area); *w += delta; break; case OB_DIRECTION_WEST: - if (near) ++e; + if (grow == near) ++e; delta = RECT_LEFT(self->frame->area) - e; *x -= delta; *w += delta; break; case OB_DIRECTION_NORTH: - if (near) ++e; + if (grow == near) ++e; delta = RECT_TOP(self->frame->area) - e; *y -= delta; *h += delta; break; case OB_DIRECTION_SOUTH: - if (near) --e; + if (grow == near) --e; delta = e - RECT_BOTTOM(self->frame->area); *h += delta; break; @@ -4201,30 +4195,3 @@ gboolean client_has_group_siblings(ObClient *self) { return self->group && self->group->members->next; } - -ObClientIcon *client_thumbnail(ObClient *self, gint wantw, gint wanth) -{ - ObClientIcon *ret; - RrPixel32 *data; - gint w, h; - - if (!self->frame->pixmap) return NULL; - if (!RrPixmapToRGBA(ob_rr_inst, self->frame->pixmap, None, &w, &h, &data)) - return NULL; - - /* resize the thumbnail (within aspect ratio) to the given sizes */ - - ret = g_new(ObClientIcon, 1); - ret->data = data; - ret->width = w; - ret->height = h; - return ret; -} - -void clienticon_free(ObClientIcon *ci) -{ - if (ci) { - g_free(ci->data); - g_free(ci); - } -}