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)
{
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 */
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))
(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
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
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,
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;
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))))
{
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);
static void client_get_startup_id(ObClient *self)
{
- if (!(OBT_PROP_GETS(self->window, NET_STARTUP_ID, utf8,
- &self->startup_id)))
+ if (!(OBT_PROP_GETS_UTF8(self->window, NET_STARTUP_ID, &self->startup_id)))
if (self->group)
- OBT_PROP_GETS(self->group->leader,
- NET_STARTUP_ID, utf8, &self->startup_id);
+ OBT_PROP_GETS_UTF8(self->group->leader, NET_STARTUP_ID,
+ &self->startup_id);
}
static void client_get_area(ObClient *self)
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) {
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)
g_free(self->original_title);
/* try netwm */
- if (!OBT_PROP_GETS(self->window, NET_WM_NAME, utf8, &data)) {
+ if (!OBT_PROP_GETS_UTF8(self->window, NET_WM_NAME, &data)) {
/* try old x stuff */
- if (!(OBT_PROP_GETS(self->window, WM_NAME, locale, &data)
- || OBT_PROP_GETS(self->window, WM_NAME, utf8, &data))) {
+ if (!OBT_PROP_GETS(self->window, WM_NAME, &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"));
g_free(data);
}
- OBT_PROP_SETS(self->window, NET_WM_VISIBLE_NAME, utf8, visible);
+ OBT_PROP_SETS(self->window, NET_WM_VISIBLE_NAME, visible);
self->title = visible;
if (self->frame)
g_free(self->icon_title);
/* try netwm */
- if (!OBT_PROP_GETS(self->window, NET_WM_ICON_NAME, utf8, &data))
+ if (!OBT_PROP_GETS_UTF8(self->window, NET_WM_ICON_NAME, &data))
/* try old x stuff */
- if (!(OBT_PROP_GETS(self->window, WM_ICON_NAME, locale, &data) ||
- OBT_PROP_GETS(self->window, WM_ICON_NAME, utf8, &data)))
+ if (!OBT_PROP_GETS(self->window, WM_ICON_NAME, &data))
data = g_strdup(self->title);
if (self->client_machine) {
g_free(data);
}
- OBT_PROP_SETS(self->window, NET_WM_VISIBLE_ICON_NAME, utf8, visible);
+ OBT_PROP_SETS(self->window, NET_WM_VISIBLE_ICON_NAME, visible);
self->icon_title = visible;
}
leader = None;
/* get the SM_CLIENT_ID */
- got = FALSE;
- if (leader)
- got = OBT_PROP_GETS(leader, SM_CLIENT_ID, locale, &self->sm_client_id);
- if (!got)
- OBT_PROP_GETS(self->window, SM_CLIENT_ID, locale, &self->sm_client_id);
+ if (leader && leader != self->window)
+ OBT_PROP_GETS_XPCS(leader, SM_CLIENT_ID, &self->sm_client_id);
+ else
+ OBT_PROP_GETS_XPCS(self->window, SM_CLIENT_ID, &self->sm_client_id);
/* get the WM_CLASS (name and class). make them "" if they are not
provided */
- got = FALSE;
- if (leader)
- got = OBT_PROP_GETSS(leader, WM_CLASS, locale, &ss);
- if (!got)
- got = OBT_PROP_GETSS(self->window, WM_CLASS, locale, &ss);
+ got = OBT_PROP_GETSS_TYPE(self->window, WM_CLASS, STRING_NO_CC, &ss);
if (got) {
if (ss[0]) {
if (self->class == NULL) self->class = g_strdup("");
/* get the WM_WINDOW_ROLE. make it "" if it is not provided */
- got = FALSE;
- if (leader)
- got = OBT_PROP_GETS(leader, WM_WINDOW_ROLE, locale, &s);
- if (!got)
- got = OBT_PROP_GETS(self->window, WM_WINDOW_ROLE, locale, &s);
+ got = OBT_PROP_GETS_XPCS(self->window, WM_WINDOW_ROLE, &s);
if (got)
self->role = s;
got = FALSE;
if (leader)
- got = OBT_PROP_GETSS(leader, WM_COMMAND, locale, &ss);
+ got = OBT_PROP_GETSS(leader, WM_COMMAND, &ss);
if (!got)
- got = OBT_PROP_GETSS(self->window, WM_COMMAND, locale, &ss);
+ got = OBT_PROP_GETSS(self->window, WM_COMMAND, &ss);
if (got) {
/* merge/mash them all together */
/* get the WM_CLIENT_MACHINE */
got = FALSE;
if (leader)
- got = OBT_PROP_GETS(leader, WM_CLIENT_MACHINE, locale, &s);
+ got = OBT_PROP_GETS(leader, WM_CLIENT_MACHINE, &s);
if (!got)
- got = OBT_PROP_GETS(self->window, WM_CLIENT_MACHINE, locale, &s);
+ got = OBT_PROP_GETS(self->window, WM_CLIENT_MACHINE, &s);
if (got) {
gchar localhost[128];
{
const gchar *type;
- OBT_PROP_SETS(self->window, OB_APP_ROLE, utf8, self->role);
- OBT_PROP_SETS(self->window, OB_APP_NAME, utf8, self->name);
- OBT_PROP_SETS(self->window, OB_APP_CLASS, utf8, self->class);
- OBT_PROP_SETS(self->window, OB_APP_TITLE, utf8, self->original_title);
+ OBT_PROP_SETS(self->window, OB_APP_ROLE, self->role);
+ OBT_PROP_SETS(self->window, OB_APP_NAME, self->name);
+ OBT_PROP_SETS(self->window, OB_APP_CLASS, self->class);
+ OBT_PROP_SETS(self->window, OB_APP_TITLE, self->original_title);
switch (self->type) {
case OB_CLIENT_TYPE_NORMAL:
case OB_CLIENT_TYPE_DOCK:
type = "dock"; break;
}
- OBT_PROP_SETS(self->window, OB_APP_TYPE, utf8, type);
+ OBT_PROP_SETS(self->window, OB_APP_TYPE, type);
}
static void client_change_wm_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)
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
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);
}