]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
RrFontHeight is meaningless with pango, it will be different for every string drawn...
[chaz/openbox] / openbox / client.c
index b7ed57b5b086e06182320f048250c78a00d6e115..2285bed853179db43500e66918340b58dd1cd4bb 100644 (file)
@@ -344,7 +344,7 @@ void client_manage(Window window)
 
         place_client(self, &x, &y);
 
-        /* make sure the window is visible */
+        /* make sure the window is visible. */
         client_find_onscreen(self, &x, &y,
                              self->frame->area.width,
                              self->frame->area.height,
@@ -353,11 +353,13 @@ void client_manage(Window window)
                                 do also. we can assume you want it back where
                                 you saved it */
                              client_normal(self) && !self->session);
-
-        if (x != ox || y != oy)
+        if (x != ox || y != oy)         
             client_move(self, x, y);
     }
 
+    keyboard_grab_for_client(self, TRUE);
+    mouse_grab_for_client(self, TRUE);
+
     client_showhide(self);
 
     /* use client_focus instead of client_activate cuz client_activate does
@@ -392,9 +394,6 @@ void client_manage(Window window)
     /* update the list hints */
     client_set_list();
 
-    keyboard_grab_for_client(self, TRUE);
-    mouse_grab_for_client(self, TRUE);
-
     ob_debug("Managed window 0x%lx (%s)\n", window, self->class);
 }
 
@@ -460,8 +459,6 @@ void client_unmanage(ObClient *self)
 
     /* tell our parent(s) that we're gone */
     if (self->transient_for == OB_TRAN_GROUP) { /* transient of group */
-        GSList *it;
-
         for (it = self->group->members; it; it = g_slist_next(it))
             if (it->data != self)
                 ((ObClient*)it->data)->transients =
@@ -613,7 +610,8 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
                                                 would be */
 
     /* XXX watch for xinerama dead areas */
-
+    /* This makes sure windows aren't entirely outside of the screen so you
+     * can't see them at all */
     a = screen_area(self->desktop);
     if (client_normal(self)) {
         if (!self->strut.right && *x >= a->x + a->width - 1)
@@ -626,9 +624,16 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
             *y = a->y;
     }
 
-    if (rude) {
-        /* this is my MOZILLA BITCHSLAP. oh ya it fucking feels good.
-           Java can suck it too. */
+    /* This here doesn't let windows even a pixel outside the screen,
+     * not applied to all windows. Not sure if it's going to stay at all.
+     * I wonder if disabling this will break struts somehow? Let's find out. */
+    if (0 && rude) {
+        /* avoid the xinerama monitor divide while we're at it,
+         * remember to fix the placement stuff to avoid it also and
+         * then remove this XXX */
+        a = screen_physical_area_monitor(client_monitor(self));
+        /* this is ben's MOZILLA BITCHSLAP. "oh ya it fucking feels good.
+           Java can suck it too." */
 
         /* dont let windows map/move into the strut unless they
            are bigger than the available area */
@@ -1446,15 +1451,17 @@ void client_update_title(ObClient *self)
     old_title = self->title;
      
     /* try netwm */
-    if (!PROP_GETS(self->window, net_wm_name, utf8, &data))
+    if (!PROP_GETS(self->window, net_wm_name, utf8, &data)) {
         /* try old x stuff */
-        if (!PROP_GETS(self->window, wm_name, locale, &data))
+        if (!PROP_GETS(self->window, wm_name, locale, &data)) {
             // http://developer.gnome.org/projects/gup/hig/draft_hig_new/windows-alert.html
             if (self->transient) {
                 data = g_strdup("");
                 goto no_number;
             } else
                 data = g_strdup("Unnamed Window");
+        }
+    }
 
     /* did the title change? then reset the title_count */
     if (old_title && 0 != strncmp(old_title, data, strlen(data)))
@@ -1788,9 +1795,8 @@ static ObStackingLayer calc_layer(ObClient *self)
     else if (self->type == OB_CLIENT_TYPE_DESKTOP)
         l = OB_STACKING_LAYER_DESKTOP;
     else if (self->type == OB_CLIENT_TYPE_DOCK) {
-        if (self->above) l = OB_STACKING_LAYER_DOCK_ABOVE;
-        else if (self->below) l = OB_STACKING_LAYER_DOCK_BELOW;
-        else l = OB_STACKING_LAYER_DOCK_NORMAL;
+        if (self->below) l = OB_STACKING_LAYER_NORMAL;
+        else l = OB_STACKING_LAYER_ABOVE;
     }
     else if (self->above) l = OB_STACKING_LAYER_ABOVE;
     else if (self->below) l = OB_STACKING_LAYER_BELOW;
@@ -2527,6 +2533,7 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
     gboolean max_horz = self->max_horz;
     gboolean max_vert = self->max_vert;
     gboolean modal = self->modal;
+    gboolean iconic = self->iconic;
     gint i;
 
     if (!(action == prop_atoms.net_wm_state_add ||
@@ -2562,6 +2569,10 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
                 action = self->skip_pager ?
                     prop_atoms.net_wm_state_remove :
                     prop_atoms.net_wm_state_add;
+            else if (state == prop_atoms.net_wm_state_hidden)
+                action = self->iconic ?
+                    prop_atoms.net_wm_state_remove :
+                    prop_atoms.net_wm_state_add;
             else if (state == prop_atoms.net_wm_state_fullscreen)
                 action = fullscreen ?
                     prop_atoms.net_wm_state_remove :
@@ -2590,6 +2601,8 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
                 self->skip_taskbar = TRUE;
             } else if (state == prop_atoms.net_wm_state_skip_pager) {
                 self->skip_pager = TRUE;
+            } else if (state == prop_atoms.net_wm_state_hidden) {
+                iconic = TRUE;
             } else if (state == prop_atoms.net_wm_state_fullscreen) {
                 fullscreen = TRUE;
             } else if (state == prop_atoms.net_wm_state_above) {
@@ -2615,6 +2628,8 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
                 self->skip_taskbar = FALSE;
             } else if (state == prop_atoms.net_wm_state_skip_pager) {
                 self->skip_pager = FALSE;
+            } else if (state == prop_atoms.net_wm_state_hidden) {
+                iconic = FALSE;
             } else if (state == prop_atoms.net_wm_state_fullscreen) {
                 fullscreen = FALSE;
             } else if (state == prop_atoms.net_wm_state_above) {
@@ -2657,6 +2672,9 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
            transients needs to change */
         client_raise(self);
     }
+    if (iconic != self->iconic)
+        client_iconify(self, iconic, FALSE);
+
     client_calc_layer(self);
     client_change_state(self); /* change the hint to reflect these changes */
 }
@@ -2990,10 +3008,19 @@ void client_set_undecorated(ObClient *self, gboolean undecorated)
     if (self->undecorated != undecorated) {
         self->undecorated = undecorated;
         client_setup_decor_and_functions(self);
+        // Make sure the client knows it might have moved. Maybe there is a
+        // better way of doing this so only one client_configure is sent, but
+        // since 125 of these are sent per second when moving the window (with
+        // user = FALSE) i doubt it matters much.
+        client_configure(self, OB_CORNER_TOPLEFT, self->area.x, self->area.y,
+                         self->area.width, self->area.height, TRUE, TRUE);
         client_change_state(self); /* reflect this in the state hints */
     }
 }
 
+/* Determines which physical monitor a client is on by calculating the
+   area of the part of the client on each monitor.  The number of the
+   monitor containing the greatest area of the client is returned.*/
 guint client_monitor(ObClient *self)
 {
     guint i;
@@ -3120,15 +3147,16 @@ void client_update_sm_client_id(ObClient *self)
  */
 gint client_directional_edge_search(ObClient *c, ObDirection dir)
 {
-    gint dest;
+    gint dest, monitor_dest;
     gint my_edge_start, my_edge_end, my_offset;
     GList *it;
-    Rect *a;
+    Rect *a, *monitor;
     
     if(!client_list)
         return -1;
 
     a = screen_area(c->desktop);
+    monitor = screen_area_monitor(c->desktop, client_monitor(c));
 
     switch(dir) {
     case OB_DIRECTION_NORTH:
@@ -3138,8 +3166,13 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
         
         /* default: top of screen */
         dest = a->y;
+        monitor_dest = monitor->y;
+        /* 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)
+            dest = monitor_dest; 
 
-        for(it = client_list; it; it = g_list_next(it)) {
+        for(it = client_list; it && my_offset != dest; it = g_list_next(it)) {
             gint his_edge_start, his_edge_end, his_offset;
             ObClient *cur = it->data;
 
@@ -3151,6 +3184,8 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
                 continue;
             if(cur->iconic)
                 continue;
+            if(cur->layer < c->layer && !config_resist_layers_below)
+                continue;
 
             his_edge_start = cur->frame->area.x;
             his_edge_end = cur->frame->area.x + cur->frame->area.width;
@@ -3179,8 +3214,13 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
 
         /* default: bottom of screen */
         dest = a->y + a->height;
+        monitor_dest = monitor->y + monitor->height;
+        /* 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)
+            dest = monitor_dest; 
 
-        for(it = client_list; it; it = g_list_next(it)) {
+        for(it = client_list; it && my_offset != dest; it = g_list_next(it)) {
             gint his_edge_start, his_edge_end, his_offset;
             ObClient *cur = it->data;
 
@@ -3192,6 +3232,8 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
                 continue;
             if(cur->iconic)
                 continue;
+            if(cur->layer < c->layer && !config_resist_layers_below)
+                continue;
 
             his_edge_start = cur->frame->area.x;
             his_edge_end = cur->frame->area.x + cur->frame->area.width;
@@ -3221,8 +3263,13 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
 
         /* default: leftmost egde of screen */
         dest = a->x;
+        monitor_dest = monitor->x;
+        /* 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)
+            dest = monitor_dest;            
 
-        for(it = client_list; it; it = g_list_next(it)) {
+        for(it = client_list; it && my_offset != dest; it = g_list_next(it)) {
             gint his_edge_start, his_edge_end, his_offset;
             ObClient *cur = it->data;
 
@@ -3234,6 +3281,8 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
                 continue;
             if(cur->iconic)
                 continue;
+            if(cur->layer < c->layer && !config_resist_layers_below)
+                continue;
 
             his_edge_start = cur->frame->area.y;
             his_edge_end = cur->frame->area.y + cur->frame->area.height;
@@ -3263,8 +3312,13 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
         
         /* default: rightmost edge of screen */
         dest = a->x + a->width;
+        monitor_dest = monitor->x + monitor->width;
+        /* 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)
+            dest = monitor_dest;            
 
-        for(it = client_list; it; it = g_list_next(it)) {
+        for(it = client_list; it && my_offset != dest; it = g_list_next(it)) {
             gint his_edge_start, his_edge_end, his_offset;
             ObClient *cur = it->data;
 
@@ -3276,6 +3330,8 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
                 continue;
             if(cur->iconic)
                 continue;
+            if(cur->layer < c->layer && !config_resist_layers_below)
+                continue;
 
             his_edge_start = cur->frame->area.y;
             his_edge_end = cur->frame->area.y + cur->frame->area.height;
@@ -3304,6 +3360,7 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
         /* not implemented */
     default:
         g_assert_not_reached();
+        dest = 0; /* suppress warning */
     }
     return dest;
 }
This page took 0.032785 seconds and 4 git commands to generate.