X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=d0cb19341ff05725afd2fe1b8236e9df19cb7d1f;hb=5a1fa9210d8d2ba483fe790750af34b0ce511da6;hp=3fac34f79ef555ed82dfa93ada2d30d72c0f590d;hpb=6fb3e62a31ad0312383bae1a0e9c28ace041da4c;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 3fac34f7..d0cb1934 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -369,7 +369,7 @@ void client_manage(Window window) placex = self->area.x; placey = self->area.y; - /* figure out placement for the window */ + /* figure out placement for the window if the window is new */ if (ob_state() == OB_STATE_RUNNING) { gboolean transient; @@ -381,6 +381,30 @@ void client_manage(Window window) transient = place_client(self, &placex, &placey, settings); + /* if the window isn't user-positioned, then make it fit inside + the visible screen area on its monitor. + + the monitor is chosen by place_client! */ + if (!(self->positioned & USPosition)) { + /* make a copy to modify */ + Rect a = *screen_area_monitor(self->desktop, client_monitor(self)); + + /* shrink by the frame's area */ + a.width -= self->frame->size.left + self->frame->size.right; + a.height -= self->frame->size.top + self->frame->size.bottom; + + /* fit the window inside the area */ + self->area.width = MIN(self->area.width, a.width); + self->area.height = MIN(self->area.height, a.height); + + ob_debug("setting window size to %dx%d\n", + self->area.width, self->area.height); + + /* adjust the frame to the client's new size */ + frame_adjust_area(self->frame, FALSE, TRUE, FALSE); + frame_adjust_client_area(self->frame); + } + /* make sure the window is visible. */ client_find_onscreen(self, &placex, &placey, self->area.width, self->area.height, @@ -462,10 +486,24 @@ void client_manage(Window window) "Not focusing the window because the time is " "too old\n"); } + /* If its a transient (and parents aren't focused) and the time + is ambiguous (either the current focus target doesn't have + a timestamp, or they are the same (we probably inherited it + from them) */ + else if (self->transient_for != NULL && + (!last_time || self->user_time == last_time)) + { + activate = FALSE; + ob_debug_type(OB_DEBUG_FOCUS, + "Not focusing the window because it is a " + "transient, and the time is very ambiguous\n"); + } /* Don't steal focus from globally active clients. I stole this idea from KWin. It seems nice. */ - if (!(focus_client->can_focus || focus_client->focus_notify)) { + else if (!(focus_client->can_focus || + focus_client->focus_notify)) + { activate = FALSE; ob_debug_type(OB_DEBUG_FOCUS, "Not focusing the window because a globally " @@ -551,6 +589,10 @@ ObClient *client_fake_manage(Window window) self->frame = frame_new(self); 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.top, self->frame->size.bottom); + /* free the ObAppSettings shallow copy */ g_free(settings); @@ -1139,15 +1181,27 @@ static void client_get_desktop(ObClient *self) self->desktop = self->transient_for->desktop; trdesk = TRUE; } else { + /* if all the group is on one desktop, then open it on the + same desktop */ GSList *it; + gboolean first = TRUE; + guint all = screen_num_desktops; /* not a valid value */ - for (it = self->group->members; it; it = g_slist_next(it)) - if (it->data != self && - !((ObClient*)it->data)->transient_for) { - self->desktop = ((ObClient*)it->data)->desktop; - trdesk = TRUE; - break; + for (it = self->group->members; it; it = g_slist_next(it)) { + ObClient *c = it->data; + if (c != self) { + if (first) { + all = c->desktop; + first = FALSE; + } + else if (all != c->desktop) + all = screen_num_desktops; /* make it invalid */ } + } + if (all != screen_num_desktops) { + self->desktop = all; + trdesk = TRUE; + } } } if (!trdesk) { @@ -1538,7 +1592,6 @@ void client_update_normal_hints(ObClient *self) { XSizeHints size; glong ret; - gint oldgravity = self->gravity; /* defaults */ self->min_ratio = 0.0f; @@ -1555,19 +1608,8 @@ void client_update_normal_hints(ObClient *self) */ self->positioned = (size.flags & (PPosition|USPosition)); - if (size.flags & PWinGravity) { + if (size.flags & PWinGravity) self->gravity = size.win_gravity; - - /* if the client has a frame, i.e. has already been mapped and - is changing its gravity */ - if (self->frame && self->gravity != oldgravity) { - /* move our idea of the client's position based on its new - gravity */ - client_convert_gravity(self, oldgravity, - &self->area.x, &self->area.y, - self->area.width, self->area.height); - } - } if (size.flags & PAspect) { if (size.min_aspect.y) @@ -1632,14 +1674,16 @@ void client_setup_decor_and_functions(ObClient *self) case OB_CLIENT_TYPE_DIALOG: case OB_CLIENT_TYPE_UTILITY: - /* these windows cannot be maximized */ - self->functions &= ~OB_CLIENT_FUNC_MAXIMIZE; + /* these windows don't have anything added or removed by default */ break; case OB_CLIENT_TYPE_MENU: case OB_CLIENT_TYPE_TOOLBAR: - /* these windows get less functionality */ - self->functions &= ~(OB_CLIENT_FUNC_ICONIFY | OB_CLIENT_FUNC_RESIZE); + /* these windows can't iconify or maximize */ + self->decorations &= ~(OB_FRAME_DECOR_ICONIFY | + OB_FRAME_DECOR_MAXIMIZE); + self->functions &= ~(OB_CLIENT_FUNC_ICONIFY | + OB_CLIENT_FUNC_MAXIMIZE); break; case OB_CLIENT_TYPE_SPLASH: @@ -1714,9 +1758,12 @@ void client_setup_decor_and_functions(ObClient *self) self->decorations &= ~OB_FRAME_DECOR_MAXIMIZE; } - if (self->max_horz && self->max_vert) + if (self->max_horz && self->max_vert) { + /* you can't resize fully maximized windows */ + self->functions &= ~OB_CLIENT_FUNC_RESIZE; /* kill the handle on fully maxed windows */ self->decorations &= ~(OB_FRAME_DECOR_HANDLE | OB_FRAME_DECOR_GRIPS); + } /* If there are no decorations to remove, don't allow the user to try toggle the state */ @@ -1889,7 +1936,8 @@ void client_update_wmhints(ObClient *self) } /* the WM_HINTS can contain an icon */ - client_update_icons(self); + if (hints->flags & IconPixmapHint) + client_update_icons(self); XFree(hints); } @@ -1941,8 +1989,14 @@ void client_update_title(ObClient *self) PROP_GETS(self->window, wm_icon_name, utf8, &data))) data = g_strdup(self->title); - PROP_SETS(self->window, net_wm_visible_icon_name, data); - self->icon_title = data; + if (self->client_machine) { + visible = g_strdup_printf("%s (%s)", data, self->client_machine); + g_free(data); + } else + visible = data; + + PROP_SETS(self->window, net_wm_visible_icon_name, visible); + self->icon_title = visible; } void client_update_strut(ObClient *self) @@ -2375,10 +2429,10 @@ static ObStackingLayer calc_layer(ObClient *self) } else if ((self->fullscreen || /* No decorations and fills the monitor = oldskool fullscreen. - But not for undecorated windows, because the user can do that + But not for maximized windows. */ (self->decorations == 0 && - !self->undecorated && + !(self->max_horz && self->max_vert) && RECT_EQUAL(self->area, *screen_physical_area_monitor (client_monitor(self))))) && @@ -2566,18 +2620,62 @@ static void client_apply_startup_state(ObClient *self) */ } -void client_convert_gravity(ObClient *self, gint gravity, gint *x, gint *y, - gint w, gint h) +void client_gravity_resize_w(ObClient *self, gint *x, gint oldw, gint neww) { - gint oldg = self->gravity; + /* these should be the current values. this is for when you're not moving, + just resizing */ + g_assert(*x == self->area.x); + g_assert(oldw == self->area.width); - /* get the frame's position from the requested stuff */ - self->gravity = gravity; - frame_client_gravity(self->frame, x, y, w, h); - self->gravity = oldg; + /* horizontal */ + switch (self->gravity) { + default: + case NorthWestGravity: + case WestGravity: + case SouthWestGravity: + case StaticGravity: + case ForgetGravity: + break; + case NorthGravity: + case CenterGravity: + case SouthGravity: + *x -= (neww - oldw) / 2; + break; + case NorthEastGravity: + case EastGravity: + case SouthEastGravity: + *x -= neww - oldw; + break; + } +} - /* get the client's position in its true gravity from that */ - frame_frame_gravity(self->frame, x, y, w, h); +void client_gravity_resize_h(ObClient *self, gint *y, gint oldh, gint newh) +{ + /* these should be the current values. this is for when you're not moving, + just resizing */ + g_assert(*y == self->area.y); + g_assert(oldh == self->area.height); + + /* vertical */ + switch (self->gravity) { + default: + case NorthWestGravity: + case NorthGravity: + case NorthEastGravity: + case StaticGravity: + case ForgetGravity: + break; + case WestGravity: + case CenterGravity: + case EastGravity: + *y -= (newh - oldh) / 2; + break; + case SouthWestGravity: + case SouthGravity: + case SouthEastGravity: + *y -= newh - oldh; + break; + } } void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, @@ -2693,7 +2791,7 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, *h = a->height; user = FALSE; /* ignore if the client can't be moved/resized when it - is entering fullscreen */ + is fullscreening */ } else if (self->max_horz || self->max_vert) { Rect *a; guint i; @@ -2711,8 +2809,8 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, *h = a->height - self->frame->size.top - self->frame->size.bottom; } - /* maximizing is not allowed if the user can't move+resize the window - */ + user = FALSE; /* ignore if the client can't be moved/resized when it + is maximizing */ } /* gets the client's position */ @@ -2908,9 +3006,8 @@ static void client_iconify_recursive(ObClient *self, self->iconic = iconic; /* update the focus lists.. iconic windows go to the bottom of - the list, put the new iconic window at the 'top of the - bottom'. */ - focus_order_to_top(self); + the list */ + focus_order_to_bottom(self); changed = TRUE; } @@ -3568,7 +3665,7 @@ static ObClientIcon* client_icon_recursive(ObClient *self, gint w, gint h) for (i = 1; i < self->nicons; ++i) { gulong diff; - diff = ABS(self->icons[0].width - w) + ABS(self->icons[0].height - h); + diff = ABS(self->icons[i].width - w) + ABS(self->icons[i].height - h); if (diff < min_diff) { min_diff = diff; min_i = i;