+ /* 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);
+
+ if (got)
+ self->role = s;
+ else
+ self->role = g_strdup("");
+
+ /* get the WM_COMMAND */
+ got = FALSE;
+
+ if (leader)
+ got = OBT_PROP_GETSS(leader, WM_COMMAND, locale, &ss);
+ if (!got)
+ got = OBT_PROP_GETSS(self->window, WM_COMMAND, locale, &ss);
+
+ if (got) {
+ /* merge/mash them all together */
+ gchar *merge = NULL;
+ gint i;
+
+ for (i = 0; ss[i]; ++i) {
+ gchar *tmp = merge;
+ if (merge)
+ merge = g_strconcat(merge, ss[i], NULL);
+ else
+ merge = g_strconcat(ss[i], NULL);
+ g_free(tmp);
+ }
+ g_strfreev(ss);
+
+ self->wm_command = merge;
+ }
+
+ /* get the WM_CLIENT_MACHINE */
+ got = FALSE;
+ if (leader)
+ got = OBT_PROP_GETS(leader, WM_CLIENT_MACHINE, locale, &s);
+ if (!got)
+ got = OBT_PROP_GETS(self->window, WM_CLIENT_MACHINE, locale, &s);
+
+ if (got) {
+ gchar localhost[128];
+ guint32 pid;
+
+ gethostname(localhost, 127);
+ localhost[127] = '\0';
+ if (strcmp(localhost, s) != 0)
+ self->client_machine = s;
+ else
+ g_free(s);
+
+ /* see if it has the PID set too (the PID requires that the
+ WM_CLIENT_MACHINE be set) */
+ if (OBT_PROP_GET32(self->window, NET_WM_PID, CARDINAL, &pid))
+ self->pid = pid;
+ }
+}
+
+static void client_change_wm_state(ObClient *self)
+{
+ gulong state[2];
+ glong old;
+
+ old = self->wmstate;
+
+ if (self->shaded || self->iconic ||
+ (self->desktop != DESKTOP_ALL && self->desktop != screen_desktop))
+ {
+ self->wmstate = IconicState;
+ } else
+ self->wmstate = NormalState;
+
+ if (old != self->wmstate) {
+ OBT_PROP_MSG(ob_screen, self->window, KDE_WM_CHANGE_STATE,
+ self->wmstate, 1, 0, 0, 0);
+
+ state[0] = self->wmstate;
+ state[1] = None;
+ OBT_PROP_SETA32(self->window, WM_STATE, WM_STATE, state, 2);
+ }
+}
+
+static void client_change_state(ObClient *self)
+{
+ gulong netstate[12];
+ guint num;
+
+ num = 0;
+ if (self->modal)
+ netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_MODAL);
+ if (self->shaded)
+ netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_SHADED);
+ if (self->iconic)
+ netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_HIDDEN);
+ if (self->skip_taskbar)
+ netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_SKIP_TASKBAR);
+ if (self->skip_pager)
+ netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_SKIP_PAGER);
+ if (self->fullscreen)
+ netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_FULLSCREEN);
+ if (self->max_vert)
+ netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_VERT);
+ if (self->max_horz)
+ netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_HORZ);
+ if (self->above)
+ netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_ABOVE);
+ if (self->below)
+ netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_BELOW);
+ if (self->demands_attention)
+ netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_DEMANDS_ATTENTION);
+ if (self->undecorated)
+ netstate[num++] = OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED);
+ OBT_PROP_SETA32(self->window, NET_WM_STATE, ATOM, netstate, num);
+
+ if (self->frame)
+ frame_adjust_state(self->frame);
+}
+
+ObClient *client_search_focus_tree(ObClient *self)
+{
+ GSList *it;
+ ObClient *ret;
+
+ for (it = self->transients; it; it = g_slist_next(it)) {
+ if (client_focused(it->data)) return it->data;
+ if ((ret = client_search_focus_tree(it->data))) return ret;
+ }
+ return NULL;
+}
+
+ObClient *client_search_focus_tree_full(ObClient *self)
+{
+ if (self->parents) {
+ GSList *it;
+
+ for (it = self->parents; it; it = g_slist_next(it)) {
+ ObClient *c = it->data;
+ if ((c = client_search_focus_tree_full(it->data))) return c;
+ }
+
+ return NULL;
+ }
+ else {
+ /* this function checks the whole tree, the client_search_focus_tree
+ does not, so we need to check this window */
+ if (client_focused(self))
+ return self;
+ return client_search_focus_tree(self);
+ }
+}
+
+ObClient *client_search_focus_group_full(ObClient *self)
+{
+ GSList *it;
+
+ if (self->group) {
+ for (it = self->group->members; it; it = g_slist_next(it)) {
+ ObClient *c = it->data;
+
+ if (client_focused(c)) return c;
+ if ((c = client_search_focus_tree(it->data))) return c;
+ }
+ } else
+ if (client_focused(self)) return self;
+ return NULL;
+}
+
+gboolean client_has_parent(ObClient *self)
+{
+ return self->parents != NULL;
+}
+
+static ObStackingLayer calc_layer(ObClient *self)
+{
+ ObStackingLayer l;
+ Rect *monitor;
+
+ monitor = screen_physical_area_monitor(client_monitor(self));
+
+ if (self->type == OB_CLIENT_TYPE_DESKTOP)
+ l = OB_STACKING_LAYER_DESKTOP;
+ else if (self->type == OB_CLIENT_TYPE_DOCK) {
+ if (self->below) l = OB_STACKING_LAYER_NORMAL;
+ else l = OB_STACKING_LAYER_ABOVE;
+ }
+ else if ((self->fullscreen ||
+ /* No decorations and fills the monitor = oldskool fullscreen.
+ But not for maximized windows.
+ */
+ (self->decorations == 0 &&
+ !(self->max_horz && self->max_vert) &&
+ RECT_EQUAL(self->area, *monitor))) &&
+ /* you are fullscreen while you or your children are focused.. */
+ (client_focused(self) || client_search_focus_tree(self) ||
+ /* you can be fullscreen if you're on another desktop */
+ (self->desktop != screen_desktop &&
+ self->desktop != DESKTOP_ALL) ||
+ /* and you can also be fullscreen if the focused client is on
+ another monitor, or nothing else is focused */
+ (!focus_client ||
+ client_monitor(focus_client) != client_monitor(self))))
+ l = OB_STACKING_LAYER_FULLSCREEN;
+ else if (self->above) l = OB_STACKING_LAYER_ABOVE;
+ else if (self->below) l = OB_STACKING_LAYER_BELOW;
+ else l = OB_STACKING_LAYER_NORMAL;
+
+ g_free(monitor);