+ 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;
+ }
+}
+
+/*! Save the properties used for app matching rules, as seen by Openbox when
+ the window mapped, so that users can still access them later if the app
+ changes them */
+static void client_save_app_rule_values(ObClient *self)
+{
+ 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);
+
+ switch (self->type) {
+ case OB_CLIENT_TYPE_NORMAL:
+ type = "normal"; break;
+ case OB_CLIENT_TYPE_DIALOG:
+ type = "dialog"; break;
+ case OB_CLIENT_TYPE_UTILITY:
+ type = "utility"; break;
+ case OB_CLIENT_TYPE_MENU:
+ type = "menu"; break;
+ case OB_CLIENT_TYPE_TOOLBAR:
+ type = "toolbar"; break;
+ case OB_CLIENT_TYPE_SPLASH:
+ type = "splash"; break;
+ case OB_CLIENT_TYPE_DESKTOP:
+ type = "desktop"; break;
+ case OB_CLIENT_TYPE_DOCK:
+ type = "dock"; break;
+ }
+ OBT_PROP_SETS(self->window, OB_APP_TYPE, utf8, type);
+}
+
+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);