X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;ds=sidebyside;f=openbox%2Fclient.c;h=3d9239e481dd95ed1acfb748b25996f7af002734;hb=5b3d5bda2439c20b33e7c8e32f58bf92b9bbed5c;hp=cb592b02af46811cdbe168b54e34e7f9a008f255;hpb=71d2605e1c24732e923333419d829f1c5f867fed;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index cb592b02..3d9239e4 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -1,5 +1,6 @@ #include "client.h" #include "dock.h" +#include "xerror.h" #include "startup.h" #include "screen.h" #include "moveresize.h" @@ -253,26 +254,26 @@ void client_manage(Window window) focus_order_add_new(self); /* focus the new window? */ - if (ob_state != State_Starting && config_focus_new) { + if (ob_state != State_Starting && config_focus_new && + (self->type == Type_Normal || self->type == Type_Dialog)) { gboolean group_foc = FALSE; if (self->group) { GSList *it; - for (it = self->group->members; it; it = it->next) + for (it = self->group->members; it; it = it->next) { if (client_focused(it->data)) { group_foc = TRUE; break; } + } } /* note the check against Type_Normal/Dialog, not client_normal(self), which would also include other types. in this case we want more strict rules for focus */ - if (((self->type == Type_Normal || - (self->type == Type_Dialog && - (group_foc || - (!self->transient_for && (!self->group || - !self->group->members->next)))))) || + if ((group_foc || + (!self->transient_for && (!self->group || + !self->group->members->next))) || client_search_focus_tree_full(self) || !focus_client || !client_normal(focus_client)) { @@ -1030,7 +1031,7 @@ void client_setup_decor_and_functions(Client *self) we may also need to be repositioned */ frame_adjust_area(self->frame, TRUE, TRUE); /* with new decor, the window's maximized size may change */ - client_remaximize(self); + client_reconfigure(self); } else { /* this makes sure that these windows appear on all desktops */ if (self->type == Type_Desktop && self->desktop != DESKTOP_ALL) @@ -1088,19 +1089,10 @@ static void client_change_allowed_actions(Client *self) } } -void client_remaximize(Client *self) +void client_reconfigure(Client *self) { - int dir; - if (self->max_horz && self->max_vert) - dir = 0; - else if (self->max_horz) - dir = 1; - else if (self->max_vert) - dir = 2; - else - return; /* not maximized */ - self->max_horz = self->max_vert = FALSE; - client_maximize(self, TRUE, dir, FALSE); + client_configure(self, Corner_TopLeft, self->area.x, self->area.y, + self->area.width, self->area.height, TRUE, TRUE); } void client_update_wmhints(Client *self) @@ -1140,18 +1132,20 @@ void client_update_wmhints(Client *self) group_remove(self->group, self); self->group = NULL; } - /* i can only have transients from the group if i am not transient - myself */ - if (hints->window_group != None && !self->transient_for) { + if (hints->window_group != None) { self->group = group_add(hints->window_group, self); - /* add other transients of the group that are already - set up */ - for (it = self->group->members; it; it = it->next) - if (it->data != self && - ((Client*)it->data)->transient_for == TRAN_GROUP) - self->transients = g_slist_append(self->transients, - it->data); + /* i can only have transients from the group if i am not + transient myself */ + if (!self->transient_for) { + /* add other transients of the group that are already + set up */ + for (it = self->group->members; it; it = it->next) + if (it->data != self && + ((Client*)it->data)->transient_for == TRAN_GROUP) + self->transients = g_slist_append(self->transients, + it->data); + } } /* the WM_HINTS can contain an icon */ @@ -1323,7 +1317,7 @@ void client_update_icons(Client *self) w = data[i++]; h = data[i++]; i += w * h; - if (i > num) break; + if (i > num || w*h == 0) break; ++self->nicons; } @@ -1337,6 +1331,8 @@ void client_update_icons(Client *self) w = self->icons[j].width = data[i++]; h = self->icons[j].height = data[i++]; + if (w*h == 0) continue; + self->icons[j].data = g_new(pixel32, w * h); for (x = 0, y = 0, t = 0; t < w * h; ++t, ++x, ++i) { if (x >= w) { @@ -1358,6 +1354,7 @@ void client_update_icons(Client *self) if (num == 2) { self->nicons++; self->icons = g_new(Icon, self->nicons); + xerror_set_ignore(TRUE); if (!render_pixmap_to_rgba(data[0], data[1], &self->icons[self->nicons-1].width, &self->icons[self->nicons-1].height, @@ -1365,6 +1362,7 @@ void client_update_icons(Client *self) g_free(&self->icons[self->nicons-1]); self->nicons--; } + xerror_set_ignore(FALSE); } g_free(data); } else { @@ -1374,6 +1372,7 @@ void client_update_icons(Client *self) if (hints->flags & IconPixmapHint) { self->nicons++; self->icons = g_new(Icon, self->nicons); + xerror_set_ignore(TRUE); if (!render_pixmap_to_rgba(hints->icon_pixmap, (hints->flags & IconMaskHint ? hints->icon_mask : None), @@ -1383,6 +1382,7 @@ void client_update_icons(Client *self) g_free(&self->icons[self->nicons-1]); self->nicons--; } + xerror_set_ignore(FALSE); } XFree(hints); } @@ -1609,10 +1609,25 @@ void client_configure(Client *self, Corner anchor, int x, int y, int w, int h, /* set the size and position if fullscreen */ if (self->fullscreen) { - x = 0; - y = 0; - w = screen_physical_size.width; - h = screen_physical_size.height; +#ifdef VIDMODE + int dot; + XF86VidModeModeLine mode; + + if (XF86VidModeGetModeLine(ob_display, ob_screen, &dot, &mode)) { + w = mode.hdisplay; + h = mode.vdisplay; + if (mode.privsize) XFree(mode.private); + } else { +#else + w = screen_physical_size.width; + h = screen_physical_size.height; +#endif +#ifdef VIDMODE + } + if (!XF86VidModeGetViewPort(ob_display, ob_screen, &x, &y)) { + x = y = 0; +#endif + } user = FALSE; /* ignore that increment etc shit when in fullscreen */ } else { /* set the size and position if maximized */ @@ -1718,7 +1733,7 @@ void client_configure(Client *self, Corner anchor, int x, int y, int w, int h, RECT_SET(self->area, x, y, w, h); - if (resized) + if (final || (resized && !config_opaque_resize)) XResizeWindow(ob_display, self->window, w, h); /* move/resize the frame to match the request */ @@ -1858,6 +1873,11 @@ void client_iconify(Client *self, gboolean iconic, gboolean curdesk) /* this puts it after the current focused window */ focus_order_remove(self); focus_order_add_new(self); + + /* this is here cuz with the VIDMODE extension, the viewport can change + while a fullscreen window is iconic, and when it uniconifies, it + would be nice if it did so to the new position of the viewport */ + client_reconfigure(self); } client_change_state(self); client_showhide(self); @@ -2025,7 +2045,7 @@ void client_set_desktop(Client *self, guint target, gboolean donthide) if (target == self->desktop) return; - g_message("Setting desktop %u", target); + g_message("Setting desktop %u", target+1); g_assert(target < screen_num_desktops || target == DESKTOP_ALL); @@ -2217,7 +2237,7 @@ void client_set_state(Client *self, Atom action, long data1, long data2) if (shaded != self->shaded) client_shade(self, shaded); client_calc_layer(self); - client_change_state(self); /* change the hint to relect these changes */ + client_change_state(self); /* change the hint to reflect these changes */ } Client *client_focus_target(Client *self) @@ -2230,18 +2250,15 @@ Client *client_focus_target(Client *self) return self; } -gboolean client_focus(Client *self) +gboolean client_can_focus(Client *self) { XEvent ev; /* choose the correct target */ self = client_focus_target(self); - if (self->desktop != DESKTOP_ALL && self->desktop != screen_desktop) { - /* update the focus lists */ - focus_order_to_top(self); + if (!self->frame->visible) return FALSE; - } if (!((self->can_focus || self->focus_notify) && (self->desktop == screen_desktop || @@ -2267,6 +2284,22 @@ gboolean client_focus(Client *self) } } + return TRUE; +} + +gboolean client_focus(Client *self) +{ + /* choose the correct target */ + self = client_focus_target(self); + + if (!client_can_focus(self)) { + if (!self->frame->visible) { + /* update the focus lists */ + focus_order_to_top(self); + } + return FALSE; + } + if (self->can_focus) /* RevertToPointerRoot causes much more headache than RevertToNone, so I choose to use it always, hopefully to find errors quicker, if any @@ -2451,3 +2484,18 @@ Client *client_find_directional(Client *c, Direction dir) return best_client; } + +void client_set_layer(Client *self, int layer) +{ + if (layer < 0) { + self->below = TRUE; + self->above = FALSE; + } else if (layer == 0) { + self->below = self->above = FALSE; + } else { + self->below = FALSE; + self->above = TRUE; + } + client_calc_layer(self); + client_change_state(self); /* reflect this in the state hints */ +}