]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
add application opacity configuration
[chaz/openbox] / openbox / client.c
index c9cd076334c3076d25149d2cb5ea70c1362b2acd..46162c319791a118aab0b2c8bcf1f057d3480152 100644 (file)
@@ -112,6 +112,8 @@ static gboolean client_can_steal_focus(ObClient *self,
                                        gboolean allow_other_desktop,
                                        gboolean request_from_user,
                                        Time steal_time, Time launch_time);
+static void client_setup_default_decor_and_functions(ObClient *self);
+static void client_setup_decor_undecorated(ObClient *self);
 
 void client_startup(gboolean reconfig)
 {
@@ -238,6 +240,18 @@ void client_manage(Window window, ObPrompt *prompt)
        that needs to be freed with g_free(). */
     settings = client_get_settings_state(self);
 
+    /* the session should get the last say though */
+    client_restore_session_state(self);
+
+    /* the per-app settings/session may have changed the decorations for
+       the window, so we setup decorations for that here.  this is a special
+       case because we want to place the window according to these decoration
+       changes.
+       we do this before setting up the frame so that it will reflect the
+       decorations of the window as it will be placed on screen.
+    */
+    client_setup_decor_undecorated(self);
+
     /* 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  */
@@ -253,9 +267,6 @@ void client_manage(Window window, ObPrompt *prompt)
        time now */
     grab_server(FALSE);
 
-    /* the session should get the last say though */
-    client_restore_session_state(self);
-
     /* this needs to occur once we have a frame, since it sets a property on
        the frame */
     client_update_opacity(self);
@@ -948,6 +959,9 @@ static ObAppSettings *client_get_settings_state(ObClient *self)
             self->desktop = settings->desktop - 1;
     }
 
+    if (settings->opacity != -1)
+       self->opacity = settings->opacity;
+
     if (settings->layer == -1) {
         self->below = TRUE;
         self->above = FALSE;
@@ -1006,6 +1020,8 @@ static void client_restore_session_state(ObClient *self)
     self->max_horz = self->session->max_horz;
     self->max_vert = self->session->max_vert;
     self->undecorated = self->session->undecorated;
+
+    self->opacity = self->session->opacity;
 }
 
 static gboolean client_restore_session_stacking(ObClient *self)
@@ -1177,11 +1193,8 @@ static void client_get_all(ObClient *self, gboolean real)
     client_get_type_and_transientness(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);
+    /* set up the maximum possible decor/functions */
+    client_setup_default_decor_and_functions(self);
 
     client_get_state(self);
 
@@ -1735,7 +1748,7 @@ void client_update_normal_hints(ObClient *self)
         ob_debug("Normal hints: not set");
 }
 
-void client_setup_decor_and_functions(ObClient *self, gboolean reconfig)
+static void client_setup_default_decor_and_functions(ObClient *self)
 {
     /* start with everything (cept fullscreen) */
     self->decorations =
@@ -1868,6 +1881,23 @@ void client_setup_decor_and_functions(ObClient *self, gboolean reconfig)
         self->functions &= ~OB_CLIENT_FUNC_MAXIMIZE;
         self->decorations &= ~OB_FRAME_DECOR_MAXIMIZE;
     }
+}
+
+/*! Set up decor for a client based on its undecorated state. */
+static void client_setup_decor_undecorated(ObClient *self)
+{
+    /* If the user requested no decorations, then remove all the decorations,
+       except the border.  But don't add a border if there wasn't one. */
+    if (self->undecorated)
+        self->decorations &= (config_theme_keepborder ?
+                              OB_FRAME_DECOR_BORDER : 0);
+}
+
+void client_setup_decor_and_functions(ObClient *self, gboolean reconfig)
+{
+    client_setup_default_decor_and_functions(self);
+
+    client_setup_decor_undecorated(self);
 
     if (self->max_horz && self->max_vert) {
         /* once upon a time you couldn't resize maximized windows, that is not
@@ -1877,12 +1907,6 @@ void client_setup_decor_and_functions(ObClient *self, gboolean reconfig)
         self->decorations &= ~(OB_FRAME_DECOR_HANDLE | OB_FRAME_DECOR_GRIPS);
     }
 
-    /* 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)
-        self->decorations &= (config_theme_keepborder ?
-                              OB_FRAME_DECOR_BORDER : 0);
-
     /* if we don't have a titlebar, then we cannot shade! */
     if (!(self->decorations & OB_FRAME_DECOR_TITLEBAR))
         self->functions &= ~OB_CLIENT_FUNC_SHADE;
@@ -2768,6 +2792,7 @@ static void client_apply_startup_state(ObClient *self,
     gboolean demands_attention = self->demands_attention;
     gboolean max_horz = self->max_horz;
     gboolean max_vert = self->max_vert;
+    guint8   opacity = self->opacity;
     Rect oldarea;
     gint l;
 
@@ -2814,6 +2839,12 @@ static void client_apply_startup_state(ObClient *self,
     if (fullscreen)
         client_fullscreen(self, TRUE);
 
+    /* make sure client_setup_decor_and_functions() is called at least once */
+    client_setup_decor_and_functions(self, FALSE);
+
+    /* make the client semi-transparent */
+    client_set_opacity(self, opacity);
+
     /* 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
@@ -2908,10 +2939,11 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
 
     /* cap any X windows at the size of an unsigned short */
     *w = MIN(*w,
-             G_MAXUSHORT - self->frame->size.left - self->frame->size.right);
+             (gint)G_MAXUSHORT
+             - self->frame->size.left - self->frame->size.right);
     *h = MIN(*h,
-             G_MAXUSHORT - self->frame->size.top - self->frame->size.bottom);
-
+             (gint)G_MAXUSHORT
+             - self->frame->size.top - self->frame->size.bottom);
 
     /* gets the frame's position */
     frame_client_gravity(self->frame, x, y);
@@ -3701,6 +3733,12 @@ void client_set_desktop(ObClient *self, guint target,
     focus_cycle_addremove(NULL, TRUE);
 }
 
+void client_set_opacity(ObClient *self, guint8 opacity)
+{
+    OBT_PROP_SET32(self->window, NET_WM_WINDOW_OPACITY, CARDINAL, 
+           opacity * 16777216);
+}
+
 gboolean client_is_direct_child(ObClient *parent, ObClient *child)
 {
     while (child != parent && (child = client_direct_parent(child)));
This page took 0.023221 seconds and 4 git commands to generate.