X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=e666d589eda3bfd512d7a5dacaf129035eb75cd8;hb=a4a5fc866db0ad56fb678740314573a06349ed7e;hp=0a150fc3b3be5bd48fa82129c7b688164f586587;hpb=145d526df4bccec222f0f6f99b3fde56a1dad4c0;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 0a150fc3..e666d589 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -108,8 +108,9 @@ static GSList *client_search_all_top_parents_internal(ObClient *self, static void client_call_notifies(ObClient *self, GSList *list); static void client_ping_event(ObClient *self, gboolean dead); static void client_prompt_kill(ObClient *self); -static gboolean client_can_steal_focus(ObClient *self, Time steal_time, - Time launch_time); +static gboolean client_can_steal_focus(ObClient *self, + gboolean allow_other_desktop, + Time steal_time, Time launch_time); void client_startup(gboolean reconfig) { @@ -244,11 +245,6 @@ void client_manage(Window window, ObPrompt *prompt) that needs to be freed with g_free(). */ settings = client_get_settings_state(self); - /* now we have all of the window's information so we can set this up. - do this before creating the frame, so it can tell that we are still - mapping and doesn't go applying things right away */ - client_setup_decor_and_functions(self, FALSE); - /* specify that if we exit, the window should not be destroyed and should be reparented back to root automatically, unless we are managing an internal ObPrompt window */ @@ -287,12 +283,12 @@ void client_manage(Window window, ObPrompt *prompt) if (ob_state() != OB_STATE_STARTING && (!self->session || self->session->focused) && /* this means focus=true for window is same as config_focus_new=true */ - ((config_focus_new || (settings && settings->focus == 1)) || + ((config_focus_new || settings->focus == 1) || client_search_focus_tree_full(self)) && /* NET_WM_USER_TIME 0 when mapping means don't focus */ (user_time != 0) && /* this checks for focus=false for the window */ - (!settings || settings->focus != 0) && + settings->focus != 0 && focus_valid_target(self, self->desktop, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, settings->focus == 1)) @@ -372,7 +368,7 @@ void client_manage(Window window, ObPrompt *prompt) (self->type == OB_CLIENT_TYPE_DIALOG || self->type == OB_CLIENT_TYPE_SPLASH || (!((self->positioned & USPosition) || - (settings && settings->pos_given)) && + settings->pos_given) && client_normal(self) && !self->session && /* don't move oldschool fullscreen windows to @@ -440,7 +436,8 @@ void client_manage(Window window, ObPrompt *prompt) ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s", activate ? "yes" : "no"); if (activate) { - activate = client_can_steal_focus(self, event_time(), launch_time); + activate = client_can_steal_focus(self, settings->focus, + event_time(), launch_time); if (!activate) { /* if the client isn't stealing focus, then hilite it so the user @@ -518,11 +515,11 @@ ObClient *client_fake_manage(Window window) uses too. this returns a shallow copy that needs to be freed */ settings = client_get_settings_state(self); - client_setup_decor_and_functions(self, FALSE); - /* create the decoration frame for the client window and adjust its size */ self->frame = frame_new(self); - frame_adjust_area(self->frame, FALSE, TRUE, TRUE); + + client_apply_startup_state(self, self->area.x, self->area.y, + self->area.width, self->area.height); ob_debug("gave extents left %d right %d top %d bottom %d", self->frame->size.left, self->frame->size.right, @@ -698,7 +695,9 @@ void client_fake_unmanage(ObClient *self) g_slice_free(ObClient, self); } -static gboolean client_can_steal_focus(ObClient *self, Time steal_time, +static gboolean client_can_steal_focus(ObClient *self, + gboolean allow_other_desktop, + Time steal_time, Time launch_time) { gboolean steal; @@ -720,11 +719,13 @@ static gboolean client_can_steal_focus(ObClient *self, Time steal_time, self->window, steal_time, launch_time, event_last_user_time); - /* if it's on another desktop */ + /* if it's on another desktop... */ if (!(self->desktop == screen_desktop || self->desktop == DESKTOP_ALL) && - /* the timestamp is from before you changed desktops */ - (!launch_time || + /* and (we dont know when it launched, and we don't want to allow + focus stealing from other desktops */ + ((!launch_time && !allow_other_desktop) || + /* or the timestamp is from before you changed desktops) */ (screen_desktop_user_time && !event_time_after(launch_time, screen_desktop_user_time)))) { @@ -1097,9 +1098,16 @@ static void client_get_all(ObClient *self, gboolean real) client_get_mwm_hints(self); /* this can change the mwmhints for special cases */ client_get_type_and_transientness(self); - client_get_state(self); client_update_normal_hints(self); + /* set up the decor/functions before getting the state. the states may + affect which functions are available, but we want to know the maximum + decor/functions are available to this window, so we can then apply them + in client_apply_startup_state() */ + client_setup_decor_and_functions(self, FALSE); + + client_get_state(self); + /* get the session related properties, these can change decorations from per-app settings */ client_get_session_ids(self); @@ -1551,7 +1559,13 @@ void client_update_sync_request_counter(ObClient *self) if (OBT_PROP_GET32(self->window, NET_WM_SYNC_REQUEST_COUNTER, CARDINAL,&i)) { + XSyncValue val; + self->sync_counter = i; + + /* this must be set when managing a new window according to EWMH */ + XSyncIntToValue(&val, 0); + XSyncSetCounter(obt_display, self->sync_counter, val); } else self->sync_counter = None; } @@ -1711,6 +1725,13 @@ void client_setup_decor_and_functions(ObClient *self, gboolean reconfig) break; } + /* If the client has no decor from its type (which never changes) then + don't allow the user to "undecorate" the window. Otherwise, allow them + to, even if there are motif hints removing the decor, because those + may change these days (e.g. chromium) */ + if (self->decorations == 0) + self->functions &= ~OB_CLIENT_FUNC_UNDECORATE; + /* Mwm Hints are applied subtractively to what has already been chosen for decor and functionality */ if (self->mwmhints.flags & OB_MWM_FLAG_DECORATIONS) { @@ -1763,17 +1784,13 @@ void client_setup_decor_and_functions(ObClient *self, gboolean reconfig) } 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 */ + /* once upon a time you couldn't resize maximized windows, that is not + the case any more though ! + + but do 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 */ - if (self->decorations == 0) - self->functions &= ~OB_CLIENT_FUNC_UNDECORATE; - /* finally, the user can have requested no decorations, which overrides everything (but doesnt give it a border if it doesnt have one) */ if (self->undecorated) @@ -1795,8 +1812,8 @@ void client_setup_decor_and_functions(ObClient *self, gboolean reconfig) client_change_allowed_actions(self); if (reconfig) - /* force reconfigure to make sure decorations are updated */ - client_reconfigure(self, TRUE); + /* reconfigure to make sure decorations are updated */ + client_reconfigure(self, FALSE); } static void client_change_allowed_actions(ObClient *self) @@ -2719,8 +2736,6 @@ static void client_apply_startup_state(ObClient *self, if (iconic) client_iconify(self, TRUE, FALSE, TRUE); - if (fullscreen) - client_fullscreen(self, TRUE); if (undecorated) client_set_undecorated(self, TRUE); if (shaded) @@ -2735,6 +2750,10 @@ static void client_apply_startup_state(ObClient *self, else if (max_horz) client_maximize(self, TRUE, 1); + /* fullscreen removes the ability to apply other states */ + if (fullscreen) + client_fullscreen(self, TRUE); + /* if the window hasn't been configured yet, then do so now, in fact the x,y,w,h may _not_ be the same as the area rect, which can end up meaning that the client isn't properly moved/resized by the fullscreen @@ -2883,11 +2902,11 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, through this code */ { gint basew, baseh, minw, minh; - gint incw, inch; + gint incw, inch, maxw, maxh; gfloat minratio, maxratio; - incw = self->fullscreen || self->max_horz ? 1 : self->size_inc.width; - inch = self->fullscreen || self->max_vert ? 1 : self->size_inc.height; + incw = self->size_inc.width; + inch = self->size_inc.height; minratio = self->fullscreen || (self->max_horz && self->max_vert) ? 0 : self->min_ratio; maxratio = self->fullscreen || (self->max_horz && self->max_vert) ? @@ -2923,6 +2942,10 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, *w -= basew; *h -= baseh; + /* the sizes to used for maximized */ + maxw = *w; + maxh = *h; + /* keep to the increments */ *w /= incw; *h /= inch; @@ -2938,6 +2961,10 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h, *w *= incw; *h *= inch; + /* if maximized/fs then don't use the size increments */ + if (self->fullscreen || self->max_horz) *w = maxw; + if (self->fullscreen || self->max_vert) *h = maxh; + *w += basew; *h += baseh; @@ -3075,16 +3102,18 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h, When user = FALSE, then the request is coming from the application itself, and we are more strict about when to send a synthetic ConfigureNotify. We strictly follow the rules of the ICCCM sec 4.1.5 - in this case (if force_reply is true) + in this case (or send one if force_reply is true) When user = TRUE, then the request is coming from "us", like when we maximize a window or something. In this case we are more lenient. We used to follow the same rules as above, but _Java_ Swing can't handle this. So just to appease Swing, when user = TRUE, we always send a synthetic ConfigureNotify to give the window its root coordinates. + Lastly, if force_reply is TRUE, we always send a + ConfigureNotify, which is needed during a resize with XSYNCronization. */ if ((!user && !resized && (rootmoved || force_reply)) || - (user && final && rootmoved)) + (user && ((!resized && force_reply) || (final && rootmoved)))) { XEvent event; @@ -3197,6 +3226,11 @@ void client_fullscreen(ObClient *self, gboolean fs) ob_debug("Window %s going fullscreen (%d)", self->title, self->fullscreen); + if (fs) { + /* make sure the window is on some monitor */ + client_find_onscreen(self, &x, &y, w, h, FALSE); + } + client_setup_decor_and_functions(self, FALSE); client_move_resize(self, x, y, w, h); @@ -3339,6 +3373,11 @@ void client_maximize(ObClient *self, gboolean max, gint dir) if (dir == 0 || dir == 2) /* vert */ self->max_vert = max; + if (max) { + /* make sure the window is on some monitor */ + client_find_onscreen(self, &x, &y, w, h, FALSE); + } + client_change_state(self); /* change the state hints on the client */ client_setup_decor_and_functions(self, FALSE); @@ -3921,7 +3960,7 @@ void client_activate(ObClient *self, gboolean desktop, if ((user && (desktop || self->desktop == DESKTOP_ALL || self->desktop == screen_desktop)) || - client_can_steal_focus(self, event_time(), CurrentTime)) + client_can_steal_focus(self, desktop, event_time(), CurrentTime)) { client_present(self, here, raise, unshade); }