]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
support clients which use true transparency 32-bit visuals.
[chaz/openbox] / openbox / client.c
index 474176888b784f03aeda80c88ad3ffaa884b3417..056a9780c75ee1672a47c3fa1cf97ec244fc84e4 100644 (file)
@@ -218,10 +218,11 @@ static ObAppSettings *get_settings(ObClient *client)
                 && !strcmp(app->name, client->name))
             ) {
             ob_debug("Window matching: %s\n", app->name);
-            /* Match if no role was specified in the per app setting, or if the string
-             * matches the beginning of the role, since apps like to set the role to
-             * things like browser-window-23c4b2f */
-            if (!app->role || !strncmp(app->role, client->role, strlen(app->role)))
+            /* Match if no role was specified in the per app setting, or if the
+             * string matches the beginning of the role, since apps like to set
+             * the role to things like browser-window-23c4b2f */
+            if (!app->role
+                || !strncmp(app->role, client->role, strlen(app->role)))
                 return app;
         }
 
@@ -311,7 +312,7 @@ void client_manage(Window window)
     XChangeSaveSet(ob_display, window, SetModeInsert);
 
     /* create the decoration frame for the client window */
-    self->frame = frame_new();
+    self->frame = frame_new(self);
 
     frame_grab_client(self->frame, self);
 
@@ -370,8 +371,9 @@ void client_manage(Window window)
 
     /* focus the new window? */
     if (ob_state() != OB_STATE_STARTING &&
-        (config_focus_new || client_search_focus_parent(self)) ||
-        (settings && settings->focus == TRUE) &&
+        ((settings && settings->focus == TRUE) ||
+         (!settings && (config_focus_new ||
+                        client_search_focus_parent(self)))) &&
         /* note the check against Type_Normal/Dialog, not client_normal(self),
            which would also include other types. in this case we want more
            strict rules for focus */
@@ -809,20 +811,22 @@ static void client_toggle_border(ObClient *self, gboolean show)
 static void client_get_all(ObClient *self)
 {
     client_get_area(self);
-    client_update_transient_for(self);
-    client_update_wmhints(self);
-    client_get_startup_id(self);
-    client_get_desktop(self);
-    client_get_shaped(self);
-
     client_get_mwm_hints(self);
-    client_get_type(self);/* this can change the mwmhints for special cases */
 
     /* The transient hint is used to pick a type, but the type can also affect
-       transiency (dialogs are always made transients). This is Havoc's idea,
-       but it is needed to make some apps work right (eg tsclient). */
+       transiency (dialogs are always made transients of their group if they
+       have one). This is Havoc's idea, but it is needed to make some apps
+       work right (eg tsclient). */
+    client_update_transient_for(self);
+    client_get_type(self);/* this can change the mwmhints for special cases */
     client_update_transient_for(self);
 
+    client_update_wmhints(self);
+    client_get_startup_id(self);
+    client_get_desktop(self);/* uses transient data/group/startup id if a
+                                desktop is not specified */
+    client_get_shaped(self);
+
     client_get_state(self);
 
     {
@@ -1302,6 +1306,7 @@ void client_setup_decor_and_functions(ObClient *self)
         if (! (self->mwmhints.decorations & OB_MWM_DECOR_ALL)) {
             if (! ((self->mwmhints.decorations & OB_MWM_DECOR_HANDLE) ||
                    (self->mwmhints.decorations & OB_MWM_DECOR_TITLE)))
+            {
                 /* if the mwm hints request no handle or title, then all
                    decorations are disabled, but keep the border if that's
                    specified */
@@ -1309,6 +1314,7 @@ void client_setup_decor_and_functions(ObClient *self)
                     self->decorations = OB_FRAME_DECOR_BORDER;
                 else
                     self->decorations = 0;
+            }
         }
     }
 
@@ -2496,7 +2502,7 @@ void client_close(ObClient *self)
     ce.xclient.window = self->window;
     ce.xclient.format = 32;
     ce.xclient.data.l[0] = prop_atoms.wm_delete_window;
-    ce.xclient.data.l[1] = event_lasttime;
+    ce.xclient.data.l[1] = event_curtime;
     ce.xclient.data.l[2] = 0l;
     ce.xclient.data.l[3] = 0l;
     ce.xclient.data.l[4] = 0l;
@@ -2817,7 +2823,7 @@ gboolean client_focus(ObClient *self)
            #799. So now it is RevertToNone again.
         */
         XSetInputFocus(ob_display, self->window, RevertToNone,
-                       event_lasttime);
+                       event_curtime);
     }
 
     if (self->focus_notify) {
@@ -2828,7 +2834,7 @@ gboolean client_focus(ObClient *self)
         ce.xclient.window = self->window;
         ce.xclient.format = 32;
         ce.xclient.data.l[0] = prop_atoms.wm_take_focus;
-        ce.xclient.data.l[1] = event_lasttime;
+        ce.xclient.data.l[1] = event_curtime;
         ce.xclient.data.l[2] = 0l;
         ce.xclient.data.l[3] = 0l;
         ce.xclient.data.l[4] = 0l;
@@ -2838,7 +2844,7 @@ gboolean client_focus(ObClient *self)
 #ifdef DEBUG_FOCUS
     ob_debug("%sively focusing %lx at %d\n",
              (self->can_focus ? "act" : "pass"),
-             self->window, (gint) event_lasttime);
+             self->window, (gint) event_curtime);
 #endif
 
     /* Cause the FocusIn to come back to us. Important for desktop switches,
@@ -2860,8 +2866,11 @@ void client_unfocus(ObClient *self)
     }
 }
 
-void client_activate(ObClient *self, gboolean here)
+void client_activate(ObClient *self, gboolean here, gboolean user)
 {
+    /* XXX do some stuff here if user is false to determine if we really want
+       to activate it or not (a parent or group member is currently active) */
+
     if (client_normal(self) && screen_showing_desktop)
         screen_show_desktop(FALSE);
     if (self->iconic)
@@ -2996,8 +3005,8 @@ ObClient *client_find_directional(ObClient *c, ObDirection dir)
             continue;
         if(cur->iconic)
             continue;
-        if(client_focus_target(cur) == cur &&
-           !(cur->can_focus || cur->focus_notify))
+        if(!(client_focus_target(cur) == cur &&
+             client_can_focus(cur)))
             continue;
 
         /* find the centre coords of this window, from the
@@ -3216,11 +3225,30 @@ void client_update_sm_client_id(ObClient *self)
                   &self->sm_client_id);
 }
 
+#define WANT_EDGE(cur, c) \
+            if(cur == c)                                                      \
+                continue;                                                     \
+            if(!client_normal(cur))                                   \
+                continue;                                                     \
+            if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL) \
+                continue;                                                     \
+            if(cur->iconic)                                                   \
+                continue;                                                     \
+            if(cur->layer < c->layer && !config_resist_layers_below)          \
+                continue;
+
+#define HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end) \
+            if ((his_edge_start >= my_edge_start && \
+                 his_edge_start <= my_edge_end) ||  \
+                (my_edge_start >= his_edge_start && \
+                 my_edge_start <= his_edge_end))    \
+                dest = his_offset;
+
 /* finds the nearest edge in the given direction from the current client
  * note to self: the edge is the -frame- edge (the actual one), not the
  * client edge.
  */
-gint client_directional_edge_search(ObClient *c, ObDirection dir)
+gint client_directional_edge_search(ObClient *c, ObDirection dir, gboolean hang)
 {
     gint dest, monitor_dest;
     gint my_edge_start, my_edge_end, my_offset;
@@ -3237,11 +3265,11 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
     case OB_DIRECTION_NORTH:
         my_edge_start = c->frame->area.x;
         my_edge_end = c->frame->area.x + c->frame->area.width;
-        my_offset = c->frame->area.y;
+        my_offset = c->frame->area.y + (hang ? c->frame->area.height : 0);
         
         /* default: top of screen */
-        dest = a->y;
-        monitor_dest = monitor->y;
+        dest = a->y + (hang ? c->frame->area.height : 0);
+        monitor_dest = monitor->y + (hang ? c->frame->area.height : 0);
         /* if the monitor edge comes before the screen edge, */
         /* use that as the destination instead. (For xinerama) */
         if (monitor_dest != dest && my_offset > monitor_dest)
@@ -3251,45 +3279,31 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
             gint his_edge_start, his_edge_end, his_offset;
             ObClient *cur = it->data;
 
-            if(cur == c)
-                continue;
-            if(!client_normal(cur))
-                continue;
-            if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
-                continue;
-            if(cur->iconic)
-                continue;
-            if(cur->layer < c->layer && !config_resist_layers_below)
-                continue;
+            WANT_EDGE(cur, c)
 
             his_edge_start = cur->frame->area.x;
             his_edge_end = cur->frame->area.x + cur->frame->area.width;
-            his_offset = cur->frame->area.y + cur->frame->area.height;
+            his_offset = cur->frame->area.y + 
+                         (hang ? 0 : cur->frame->area.height);
 
             if(his_offset + 1 > my_offset)
                 continue;
 
             if(his_offset < dest)
                 continue;
-            
-            if(his_edge_start >= my_edge_start &&
-               his_edge_start <= my_edge_end)
-                dest = his_offset;
-
-            if(my_edge_start >= his_edge_start &&
-               my_edge_start <= his_edge_end)
-                dest = his_offset;
 
+            HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end)
         }
         break;
     case OB_DIRECTION_SOUTH:
         my_edge_start = c->frame->area.x;
         my_edge_end = c->frame->area.x + c->frame->area.width;
-        my_offset = c->frame->area.y + c->frame->area.height;
+        my_offset = c->frame->area.y + (hang ? 0 : c->frame->area.height);
 
         /* default: bottom of screen */
-        dest = a->y + a->height;
-        monitor_dest = monitor->y + monitor->height;
+        dest = a->y + a->height - (hang ? c->frame->area.height : 0);
+        monitor_dest = monitor->y + monitor->height -
+                       (hang ? c->frame->area.height : 0);
         /* if the monitor edge comes before the screen edge, */
         /* use that as the destination instead. (For xinerama) */
         if (monitor_dest != dest && my_offset < monitor_dest)
@@ -3299,20 +3313,12 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
             gint his_edge_start, his_edge_end, his_offset;
             ObClient *cur = it->data;
 
-            if(cur == c)
-                continue;
-            if(!client_normal(cur))
-                continue;
-            if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
-                continue;
-            if(cur->iconic)
-                continue;
-            if(cur->layer < c->layer && !config_resist_layers_below)
-                continue;
+            WANT_EDGE(cur, c)
 
             his_edge_start = cur->frame->area.x;
             his_edge_end = cur->frame->area.x + cur->frame->area.width;
-            his_offset = cur->frame->area.y;
+            his_offset = cur->frame->area.y +
+                         (hang ? cur->frame->area.height : 0);
 
 
             if(his_offset - 1 < my_offset)
@@ -3320,25 +3326,18 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
             
             if(his_offset > dest)
                 continue;
-            
-            if(his_edge_start >= my_edge_start &&
-               his_edge_start <= my_edge_end)
-                dest = his_offset;
-
-            if(my_edge_start >= his_edge_start &&
-               my_edge_start <= his_edge_end)
-                dest = his_offset;
 
+            HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end)
         }
         break;
     case OB_DIRECTION_WEST:
         my_edge_start = c->frame->area.y;
         my_edge_end = c->frame->area.y + c->frame->area.height;
-        my_offset = c->frame->area.x;
+        my_offset = c->frame->area.x + (hang ? c->frame->area.width : 0);
 
         /* default: leftmost egde of screen */
-        dest = a->x;
-        monitor_dest = monitor->x;
+        dest = a->x + (hang ? c->frame->area.width : 0);
+        monitor_dest = monitor->x + (hang ? c->frame->area.width : 0);
         /* if the monitor edge comes before the screen edge, */
         /* use that as the destination instead. (For xinerama) */
         if (monitor_dest != dest && my_offset > monitor_dest)
@@ -3348,46 +3347,31 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
             gint his_edge_start, his_edge_end, his_offset;
             ObClient *cur = it->data;
 
-            if(cur == c)
-                continue;
-            if(!client_normal(cur))
-                continue;
-            if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
-                continue;
-            if(cur->iconic)
-                continue;
-            if(cur->layer < c->layer && !config_resist_layers_below)
-                continue;
+            WANT_EDGE(cur, c)
 
             his_edge_start = cur->frame->area.y;
             his_edge_end = cur->frame->area.y + cur->frame->area.height;
-            his_offset = cur->frame->area.x + cur->frame->area.width;
+            his_offset = cur->frame->area.x +
+                         (hang ? 0 : cur->frame->area.width);
 
             if(his_offset + 1 > my_offset)
                 continue;
-            
+
             if(his_offset < dest)
                 continue;
-            
-            if(his_edge_start >= my_edge_start &&
-               his_edge_start <= my_edge_end)
-                dest = his_offset;
-
-            if(my_edge_start >= his_edge_start &&
-               my_edge_start <= his_edge_end)
-                dest = his_offset;
-                
 
+            HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end)
         }
-        break;
+       break;
     case OB_DIRECTION_EAST:
         my_edge_start = c->frame->area.y;
         my_edge_end = c->frame->area.y + c->frame->area.height;
-        my_offset = c->frame->area.x + c->frame->area.width;
+        my_offset = c->frame->area.x + (hang ? 0 : c->frame->area.width);
         
         /* default: rightmost edge of screen */
-        dest = a->x + a->width;
-        monitor_dest = monitor->x + monitor->width;
+        dest = a->x + a->width - (hang ? c->frame->area.width : 0);
+        monitor_dest = monitor->x + monitor->width -
+                       (hang ? c->frame->area.width : 0);
         /* if the monitor edge comes before the screen edge, */
         /* use that as the destination instead. (For xinerama) */
         if (monitor_dest != dest && my_offset < monitor_dest)
@@ -3397,35 +3381,20 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
             gint his_edge_start, his_edge_end, his_offset;
             ObClient *cur = it->data;
 
-            if(cur == c)
-                continue;
-            if(!client_normal(cur))
-                continue;
-            if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
-                continue;
-            if(cur->iconic)
-                continue;
-            if(cur->layer < c->layer && !config_resist_layers_below)
-                continue;
+            WANT_EDGE(cur, c)
 
             his_edge_start = cur->frame->area.y;
             his_edge_end = cur->frame->area.y + cur->frame->area.height;
-            his_offset = cur->frame->area.x;
+            his_offset = cur->frame->area.x +
+                         (hang ? cur->frame->area.width : 0);
 
             if(his_offset - 1 < my_offset)
                 continue;
             
             if(his_offset > dest)
                 continue;
-            
-            if(his_edge_start >= my_edge_start &&
-               his_edge_start <= my_edge_end)
-                dest = his_offset;
-
-            if(my_edge_start >= his_edge_start &&
-               my_edge_start <= his_edge_end)
-                dest = his_offset;
 
+            HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end)
         }
         break;
     case OB_DIRECTION_NORTHEAST:
This page took 0.029937 seconds and 4 git commands to generate.