Don't uniconify locked windows via _NET_ACTIVE_WINDOW
[mikachu/openbox.git] / openbox / client.c
index 323f727..2fbd020 100644 (file)
@@ -1169,14 +1169,14 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
            only limiting the application.
         */
         if (client_normal(self)) {
-            if (!self->strut.right && *x + fw/10 >= a->x + a->width - 1)
-                *x = a->x + a->width - fw/10;
-            if (!self->strut.bottom && *y + fh/10 >= a->y + a->height - 1)
-                *y = a->y + a->height - fh/10;
-            if (!self->strut.left && *x + fw*9/10 - 1 < a->x)
-                *x = a->x - fw*9/10;
-            if (!self->strut.top && *y + fh*9/10 - 1 < a->y)
-                *y = a->y - fh*9/10;
+            if (!self->strut.right && *x + fw/100 >= a->x + a->width - 1)
+                *x = a->x + a->width - fw/100;
+            if (!self->strut.bottom && *y + fh/100 >= a->y + a->height - 1)
+                *y = a->y + a->height - fh/100;
+            if (!self->strut.left && *x + fw*99/100 - 1 < a->x)
+                *x = a->x - fw*99/100;
+            if (!self->strut.top && *y + fh*99/100 - 1 < a->y)
+                *y = a->y - fh*99/100;
         }
 
         /* This here doesn't let windows even a pixel outside the
@@ -1373,6 +1373,8 @@ static void client_get_state(ObClient *self)
                 self->demands_attention = TRUE;
             else if (state[i] == OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED))
                 self->undecorated = TRUE;
+            else if (state[i] == OBT_PROP_ATOM(OB_WM_STATE_LOCKED))
+                self->locked = TRUE;
         }
 
         g_free(state);
@@ -2098,7 +2100,6 @@ void client_update_title(ObClient *self)
     gchar *data = NULL;
     gchar *visible = NULL;
 
-    g_free(self->title);
     g_free(self->original_title);
 
     /* try netwm */
@@ -2111,8 +2112,14 @@ void client_update_title(ObClient *self)
    http://developer.gnome.org/projects/gup/hig/draft_hig_new/windows-alert.html
    */
                 data = g_strdup("");
-            } else
-                data = g_strdup(_("Unnamed Window"));
+            } else {
+                if (self->class && *self->class)
+                    data = g_strdup(self->class);
+                else if (self->name && *self->name)
+                    data = g_strdup(self->name);
+                else
+                    data = g_strdup(_("Unnamed Window"));
+            }
         }
     }
     self->original_title = g_strdup(data);
@@ -2132,15 +2139,18 @@ void client_update_title(ObClient *self)
         g_free(data);
     }
 
-    OBT_PROP_SETS(self->window, NET_WM_VISIBLE_NAME, visible);
-    self->title = visible;
+    if (!self->title || strcmp(self->title, visible)) {
+        OBT_PROP_SETS(self->window, NET_WM_VISIBLE_NAME, visible);
+        g_free(self->title);
+        self->title = visible;
+    } else
+        g_free(visible);
 
     if (self->frame)
         frame_adjust_title(self->frame);
 
     /* update the icon title */
     data = NULL;
-    g_free(self->icon_title);
 
     /* try netwm */
     if (!OBT_PROP_GETS_UTF8(self->window, NET_WM_ICON_NAME, &data))
@@ -2163,8 +2173,12 @@ void client_update_title(ObClient *self)
         g_free(data);
     }
 
-    OBT_PROP_SETS(self->window, NET_WM_VISIBLE_ICON_NAME, visible);
-    self->icon_title = visible;
+    if (!self->icon_title || strcmp(self->icon_title, visible)) {
+        OBT_PROP_SETS(self->window, NET_WM_VISIBLE_ICON_NAME, visible);
+        g_free(self->icon_title);
+        self->icon_title = visible;
+    } else
+        g_free(visible);
 }
 
 void client_update_strut(ObClient *self)
@@ -2529,7 +2543,7 @@ static void client_change_wm_state(ObClient *self)
 
 static void client_change_state(ObClient *self)
 {
-    gulong netstate[12];
+    gulong netstate[13];
     guint num;
 
     num = 0;
@@ -2557,6 +2571,8 @@ static void client_change_state(ObClient *self)
         netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_DEMANDS_ATTENTION);
     if (self->undecorated)
         netstate[num++] = OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED);
+    if (self->locked)
+        netstate[num++] = OBT_PROP_ATOM(OB_WM_STATE_LOCKED);
     OBT_PROP_SETA32(self->window, NET_WM_STATE, ATOM, netstate, num);
 
     if (self->frame)
@@ -2994,11 +3010,12 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
     frame_adjust_area(self->frame, FALSE, TRUE, TRUE);
 
     /* cap any X windows at the size of an unsigned short */
+    /* actually make that a bit less, X shits itself on windows this large too */
     *w = MIN(*w,
-             (gint)G_MAXUSHORT
+             (gint)4096
              - self->frame->size.left - self->frame->size.right);
     *h = MIN(*h,
-             (gint)G_MAXUSHORT
+             (gint)4096
              - self->frame->size.top - self->frame->size.bottom);
 
     /* gets the frame's position */
@@ -3064,6 +3081,8 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
         maxratio = self->fullscreen || (self->max_horz && self->max_vert) ?
             0 : self->max_ratio;
 
+        /* XXX TODO FIXME these two fallbacks don't check that the fallback
+         * value itself is specified before using it */
         /* base size is substituted with min size if not specified */
         if (self->base_size.width >= 0 || self->base_size.height >= 0) {
             basew = self->base_size.width;
@@ -3122,8 +3141,10 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
 
         /* adjust the height to match the width for the aspect ratios.
            for this, min size is not substituted for base size ever. */
-        *w -= self->base_size.width;
-        *h -= self->base_size.height;
+        if (self->base_size.width >= 0 && self->base_size.height >= 0) {
+            *w -= self->base_size.width;
+            *h -= self->base_size.height;
+        }
 
         if (minratio)
             if (*h * minratio > *w) {
@@ -3146,8 +3167,10 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
                 }
             }
 
-        *w += self->base_size.width;
-        *h += self->base_size.height;
+        if (self->base_size.width >= 0 && self->base_size.height >= 0) {
+            *w += self->base_size.width;
+            *h += self->base_size.height;
+        }
     }
 
     /* these override the above states! if you cant move you can't move! */
@@ -3857,6 +3880,7 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
     gboolean shaded = self->shaded;
     gboolean fullscreen = self->fullscreen;
     gboolean undecorated = self->undecorated;
+    gboolean locked = self->locked;
     gboolean max_horz = self->max_horz;
     gboolean max_vert = self->max_vert;
     gboolean modal = self->modal;
@@ -3904,6 +3928,8 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
                 value = self->demands_attention;
             else if (state == OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED))
                 value = undecorated;
+            else if (state == OBT_PROP_ATOM(OB_WM_STATE_LOCKED))
+                value = locked;
             else
                 g_assert_not_reached();
             action = value ? OBT_PROP_ATOM(NET_WM_STATE_REMOVE) :
@@ -3942,6 +3968,8 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
             demands_attention = value;
         } else if (state == OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED)) {
             undecorated = value;
+        } else if (state == OBT_PROP_ATOM(OB_WM_STATE_LOCKED)) {
+            locked = value;
         }
     }
 
@@ -3970,6 +3998,8 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
         client_shade(self, shaded);
     if (undecorated != self->undecorated)
         client_set_undecorated(self, undecorated);
+    if (locked != self->locked)
+        client_set_locked(self, locked);
     if (above != self->above || below != self->below) {
         self->above = above;
         self->below = below;
@@ -4121,6 +4151,9 @@ void client_activate(ObClient *self, gboolean desktop,
 {
     self = client_focus_target(self);
 
+    if (self->iconic && self->locked)
+        return;
+
     if (client_can_steal_focus(self, desktop, user, event_time(), CurrentTime))
         client_present(self, here, raise, unshade);
     else
@@ -4197,6 +4230,14 @@ void client_set_layer(ObClient *self, gint layer)
     client_change_state(self); /* reflect this in the state hints */
 }
 
+void client_set_locked(ObClient *self, gboolean locked)
+{
+    if (self->locked != locked) {
+        self->locked = locked;
+        client_change_state(self);
+    }
+}
+
 void client_set_undecorated(ObClient *self, gboolean undecorated)
 {
     if (self->undecorated != undecorated &&