]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
the xinerama patch from john russell, modified a bit and merged the move_onmonitor...
[chaz/openbox] / openbox / client.c
index 7f837e0612b954abaee39bf01644ccf3adfb4aeb..d5069b0a6e0563cf861c7835d366acc5860010ab 100644 (file)
@@ -344,20 +344,19 @@ void client_manage(Window window)
 
         place_client(self, &x, &y);
 
-        /* make sure the window is visible */
-        client_find_onscreen(self, &x, &y,
-                             self->frame->area.width,
-                             self->frame->area.height,
-                             /* non-normal clients has less rules, and
-                                windows that are being restored from a session
-                                do also. we can assume you want it back where
-                                you saved it */
-                             client_normal(self) && !self->session);
-
-        if (x != ox || y != oy)
-            client_move(self, x, y);
+        /* make sure the window is visible.
+           
+           this is about the rude parameter:
+           non-normal clients has less rules, and
+           windows that are being restored from a session
+           do also. we can assume you want it back where
+           you saved it */
+        client_move_onscreen(self, client_normal(self) && !self->session);
     }
 
+    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 +391,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 +456,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 =
@@ -614,7 +608,8 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
 
     /* XXX watch for xinerama dead areas */
 
-    a = screen_area(self->desktop);
+    /* a = screen_area(self->desktop); */
+    a = screen_physical_area_monitor(client_monitor(self));
     if (client_normal(self)) {
         if (!self->strut.right && *x >= a->x + a->width - 1)
             *x = a->x + a->width - self->frame->area.width;
@@ -1446,14 +1441,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
+            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)))
@@ -2526,6 +2524,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 ||
@@ -2561,6 +2560,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 :
@@ -2589,6 +2592,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) {
@@ -2614,6 +2619,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) {
@@ -2656,6 +2663,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 */
 }
@@ -2896,7 +2906,10 @@ ObClient *client_find_directional(ObClient *c, ObDirection dir)
             continue;
         if (!client_normal(cur))
             continue;
-        if(c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
+        /* using c->desktop instead of screen_desktop doesn't work if the
+         * current window was omnipresent, hope this doesn't have any other
+         * side effects */
+        if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
             continue;
         if(cur->iconic)
             continue;
@@ -2990,6 +3003,9 @@ void client_set_undecorated(ObClient *self, gboolean undecorated)
     }
 }
 
+/* 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;
@@ -3116,15 +3132,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:
@@ -3134,8 +3151,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;
 
@@ -3143,10 +3165,12 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
                 continue;
             if(!client_normal(cur))
                 continue;
-            if(c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
+            if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
                 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;
@@ -3175,8 +3199,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;
 
@@ -3184,10 +3213,12 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
                 continue;
             if(!client_normal(cur))
                 continue;
-            if(c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
+            if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
                 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;
@@ -3217,8 +3248,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;
 
@@ -3226,10 +3262,12 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
                 continue;
             if(!client_normal(cur))
                 continue;
-            if(c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
+            if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
                 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;
@@ -3259,8 +3297,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;
 
@@ -3268,10 +3311,12 @@ gint client_directional_edge_search(ObClient *c, ObDirection dir)
                 continue;
             if(!client_normal(cur))
                 continue;
-            if(c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
+            if(screen_desktop != cur->desktop && cur->desktop != DESKTOP_ALL)
                 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;
@@ -3300,6 +3345,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.031517 seconds and 4 git commands to generate.