]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
a number for placing windows, to keep them on screen, but let you place them off...
[chaz/openbox] / openbox / client.c
index ffc0488f4083b08c9a76bb0ffe5ca2350d3dc000..b8a2ea2454e7d3a384b434d061189b158d36f31c 100644 (file)
@@ -382,7 +382,8 @@ void client_manage(Window window)
                              */
                              ob_state() == OB_STATE_RUNNING &&
                              (transient ||
-                              (!(self->positioned & USPosition) &&
+                              (!((self->positioned & USPosition) ||
+                                 (settings && settings->pos_given)) &&
                                client_normal(self) &&
                                !self->session)));
     }
@@ -983,10 +984,15 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
     for (i = 0; i < screen_num_monitors; ++i) {
         Rect *a;
 
-        if (!screen_physical_area_monitor_contains(i, &desired))
-            continue;
+        if (!screen_physical_area_monitor_contains(i, &desired)) {
+            if (i < screen_num_monitors - 1)
+                continue;
 
-        a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &desired);
+            /* the window is not inside any monitor! so just use the first
+               one */
+            a = screen_area(self->desktop, 0, NULL);
+        } else
+            a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &desired);
 
         /* This makes sure windows aren't entirely outside of the screen so you
            can't see them at all.
@@ -1003,7 +1009,7 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
             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 - fw*9/10;
+                *y = a->y - fh*9/10;
         }
 
         /* This here doesn't let windows even a pixel outside the
@@ -1337,7 +1343,7 @@ static void client_update_transient_tree(ObClient *self,
        C is transient for B
        A can't be transient for C or we have a cycle
     */
-    if (!newgtran &&
+    if (!newgtran && newgroup &&
         (!newparent ||
          !client_search_top_direct_parent(newparent)->transient_for_group) &&
         client_normal(self))
@@ -1884,10 +1890,10 @@ void client_update_title(ObClient *self)
         if (!(PROP_GETS(self->window, wm_name, locale, &data)
               || PROP_GETS(self->window, wm_name, utf8, &data))) {
             if (self->transient) {
-                /*
-                  GNOME alert windows are not given titles:
-                  http://developer.gnome.org/projects/gup/hig/draft_hig_new/windows-alert.html
-                */
+    /*
+    GNOME alert windows are not given titles:
+    http://developer.gnome.org/projects/gup/hig/draft_hig_new/windows-alert.html
+    */
                 data = g_strdup("");
             } else
                 data = g_strdup("Unnamed Window");
@@ -3849,6 +3855,96 @@ ObClient *client_search_transient(ObClient *self, ObClient *search)
     return NULL;
 }
 
+static void detect_edge(Rect area, ObDirection dir,
+                        gint my_head, gint my_size,
+                        gint my_edge_start, gint my_edge_size,
+                        gint *dest, gboolean *near_edge)
+{
+    gint edge_start, edge_size, head, tail;
+    gboolean skip_head = FALSE, skip_tail = FALSE;
+
+    switch(dir) {
+        case OB_DIRECTION_NORTH:
+        case OB_DIRECTION_SOUTH:
+            edge_start = area.x;
+            edge_size = area.width;
+            break;
+        case OB_DIRECTION_EAST:
+        case OB_DIRECTION_WEST:
+            edge_start = area.y;
+            edge_size = area.height;
+            break;
+        default:
+            g_assert_not_reached();
+    }
+
+    /* do we collide with this window? */
+    if (!RANGES_INTERSECT(my_edge_start, my_edge_size,
+                edge_start, edge_size))
+        return;
+
+    switch(dir) {
+        case OB_DIRECTION_NORTH:
+            head = RECT_BOTTOM(area);
+            tail = RECT_TOP(area);
+            break;
+        case OB_DIRECTION_SOUTH:
+            head = RECT_TOP(area);
+            tail = RECT_BOTTOM(area);
+            break;
+        case OB_DIRECTION_EAST:
+            head = RECT_LEFT(area);
+            tail = RECT_RIGHT(area);
+            break;
+        case OB_DIRECTION_WEST:
+            head = RECT_RIGHT(area);
+            tail = RECT_LEFT(area);
+            break;
+        default:
+            g_assert_not_reached();
+    }
+    switch(dir) {
+        case OB_DIRECTION_NORTH:
+        case OB_DIRECTION_WEST:
+            if (my_head <= head + 1)
+                skip_head = TRUE;
+            if (my_head + my_size - 1 <= tail)
+                skip_tail = TRUE;
+            if (head < *dest)
+                skip_head = TRUE;
+            if (tail - my_size < *dest)
+                skip_tail = TRUE;
+            break;
+        case OB_DIRECTION_SOUTH:
+        case OB_DIRECTION_EAST:
+            if (my_head >= head - 1)
+                skip_head = TRUE;
+            if (my_head - my_size + 1 >= tail)
+                skip_tail = TRUE;
+            if (head > *dest)
+                skip_head = TRUE;
+            if (tail + my_size > *dest)
+                skip_tail = TRUE;
+            break;
+        default:
+            g_assert_not_reached();
+    }
+
+    ob_debug("my head %d size %d\n", my_head, my_size);
+    ob_debug("head %d tail %d deest %d\n", head, tail, *dest);
+    if (!skip_head) {
+        ob_debug("using near edge %d\n", head);
+        *dest = head;
+        *near_edge = TRUE;
+    }
+    else if (!skip_tail) {
+        ob_debug("using far edge %d\n", tail);
+        *dest = tail;
+        *near_edge = FALSE;
+    }
+
+}
+
 void client_find_edge_directional(ObClient *self, ObDirection dir,
                                   gint my_head, gint my_size,
                                   gint my_edge_start, gint my_edge_size,
@@ -3856,6 +3952,7 @@ void client_find_edge_directional(ObClient *self, ObDirection dir,
 {
     GList *it;
     Rect *a, *mon;
+    Rect dock_area;
     gint edge;
 
     a = screen_area(self->desktop, SCREEN_AREA_ALL_MONITORS,
@@ -3897,8 +3994,6 @@ void client_find_edge_directional(ObClient *self, ObDirection dir,
 
     for(it = client_list; it; it = g_list_next(it)) {
         ObClient *cur = it->data;
-        gint edge_start, edge_size, head, tail;
-        gboolean skip_head = FALSE, skip_tail = FALSE;
 
         /* skip windows to not bump into */
         if (cur == self)
@@ -3911,87 +4006,12 @@ void client_find_edge_directional(ObClient *self, ObDirection dir,
 
         ob_debug("trying window %s\n", cur->title);
 
-        switch(dir) {
-        case OB_DIRECTION_NORTH:
-        case OB_DIRECTION_SOUTH:
-            edge_start = cur->frame->area.x;
-            edge_size = cur->frame->area.width;
-            break;
-        case OB_DIRECTION_EAST:
-        case OB_DIRECTION_WEST:
-            edge_start = cur->frame->area.y;
-            edge_size = cur->frame->area.height;
-            break;
-        default:
-            g_assert_not_reached();
-        }
-
-        /* do we collide with this window? */
-        if (!RANGES_INTERSECT(my_edge_start, my_edge_size,
-                              edge_start, edge_size))
-            continue;
-
-        switch(dir) {
-        case OB_DIRECTION_NORTH:
-            head = RECT_BOTTOM(cur->frame->area);
-            tail = RECT_TOP(cur->frame->area);
-            break;
-        case OB_DIRECTION_SOUTH:
-            head = RECT_TOP(cur->frame->area);
-            tail = RECT_BOTTOM(cur->frame->area);
-            break;
-        case OB_DIRECTION_EAST:
-            head = RECT_LEFT(cur->frame->area);
-            tail = RECT_RIGHT(cur->frame->area);
-            break;
-        case OB_DIRECTION_WEST:
-            head = RECT_RIGHT(cur->frame->area);
-            tail = RECT_LEFT(cur->frame->area);
-            break;
-        default:
-            g_assert_not_reached();
-        }
-
-        switch(dir) {
-        case OB_DIRECTION_NORTH:
-        case OB_DIRECTION_WEST:
-            if (my_head <= head + 1)
-                skip_head = TRUE;
-            if (my_head + my_size - 1 <= tail + 1)
-                skip_tail = TRUE;
-            if (head < *dest)
-                skip_head = TRUE;
-            if (tail - my_size < *dest)
-                skip_tail = TRUE;
-            break;
-        case OB_DIRECTION_SOUTH:
-        case OB_DIRECTION_EAST:
-            if (my_head >= head - 1)
-                skip_head = TRUE;
-            if (my_head - my_size + 1 >= tail - 1)
-                skip_tail = TRUE;
-            if (head > *dest)
-                skip_head = TRUE;
-            if (tail + my_size > *dest)
-                skip_tail = TRUE;
-            break;
-        default:
-            g_assert_not_reached();
-        }
-
-        ob_debug("my head %d size %d\n", my_head, my_size);
-        ob_debug("head %d tail %d deest %d\n", head, tail, *dest);
-        if (!skip_head) {
-            ob_debug("using near edge %d\n", head);
-            *dest = head;
-            *near_edge = TRUE;
-        }
-        else if (!skip_tail) {
-            ob_debug("using far edge %d\n", tail);
-            *dest = tail;
-            *near_edge = FALSE;
-        }
+        detect_edge(cur->frame->area, dir, my_head, my_size, my_edge_start,
+                    my_edge_size, dest, near_edge);
     }
+    dock_get_area(&dock_area);
+    detect_edge(dock_area, dir, my_head, my_size, my_edge_start,
+                my_edge_size, dest, near_edge);
 }
 
 void client_find_move_directional(ObClient *self, ObDirection dir,
@@ -4065,36 +4085,36 @@ void client_find_resize_directional(ObClient *self, ObDirection side,
                                     gboolean grow,
                                     gint *x, gint *y, gint *w, gint *h)
 {
-    gint head, size;
+    gint head;
     gint e, e_start, e_size, delta;
     gboolean near;
     ObDirection dir;
 
     switch (side) {
     case OB_DIRECTION_EAST:
-        head = RECT_RIGHT(self->frame->area) + (self->size_inc.width - 1);
-        size = self->frame->area.width;
+        head = RECT_RIGHT(self->frame->area) +
+            (self->size_inc.width - 1) * (grow ? 1 : -1);
         e_start = RECT_TOP(self->frame->area);
         e_size = self->frame->area.height;
         dir = grow ? OB_DIRECTION_EAST : OB_DIRECTION_WEST;
         break;
     case OB_DIRECTION_WEST:
-        head = RECT_LEFT(self->frame->area) - (self->size_inc.width - 1);
-        size = self->frame->area.width;
+        head = RECT_LEFT(self->frame->area) -
+            (self->size_inc.width - 1) * (grow ? 1 : -1);
         e_start = RECT_TOP(self->frame->area);
         e_size = self->frame->area.height;
         dir = grow ? OB_DIRECTION_WEST : OB_DIRECTION_EAST;
         break;
     case OB_DIRECTION_NORTH:
-        head = RECT_TOP(self->frame->area) - (self->size_inc.height - 1);
-        size = self->frame->area.height;
+        head = RECT_TOP(self->frame->area) -
+            (self->size_inc.height - 1) * (grow ? 1 : -1);
         e_start = RECT_LEFT(self->frame->area);
         e_size = self->frame->area.width;
         dir = grow ? OB_DIRECTION_NORTH : OB_DIRECTION_SOUTH;
         break;
     case OB_DIRECTION_SOUTH:
-        head = RECT_BOTTOM(self->frame->area) + (self->size_inc.height - 1);
-        size = self->frame->area.height;
+        head = RECT_BOTTOM(self->frame->area) +
+            (self->size_inc.height - 1) * (grow ? 1 : -1);
         e_start = RECT_LEFT(self->frame->area);
         e_size = self->frame->area.width;
         dir = grow ? OB_DIRECTION_SOUTH : OB_DIRECTION_NORTH;
@@ -4103,32 +4123,34 @@ void client_find_resize_directional(ObClient *self, ObDirection side,
         g_assert_not_reached();
     }
 
-    client_find_edge_directional(self, dir, head, size,
+    ob_debug("head %d dir %d\n", head, dir);
+    client_find_edge_directional(self, dir, head, 1,
                                  e_start, e_size, &e, &near);
+    ob_debug("edge %d\n", e);
     *x = self->frame->area.x;
     *y = self->frame->area.y;
     *w = self->frame->area.width;
     *h = self->frame->area.height;
     switch (side) {
     case OB_DIRECTION_EAST:
-        if (near) --e;
+        if (grow == near) --e;
         delta = e - RECT_RIGHT(self->frame->area);
         *w += delta;
         break;
     case OB_DIRECTION_WEST:
-        if (near) ++e;
+        if (grow == near) ++e;
         delta = RECT_LEFT(self->frame->area) - e;
         *x -= delta;
         *w += delta;
         break;
     case OB_DIRECTION_NORTH:
-        if (near) ++e;
+        if (grow == near) ++e;
         delta = RECT_TOP(self->frame->area) - e;
         *y -= delta;
         *h += delta;
         break;
     case OB_DIRECTION_SOUTH:
-        if (near) --e;
+        if (grow == near) --e;
         delta = e - RECT_BOTTOM(self->frame->area);
         *h += delta;
         break;
@@ -4173,30 +4195,3 @@ gboolean client_has_group_siblings(ObClient *self)
 {
     return self->group && self->group->members->next;
 }
-
-ObClientIcon *client_thumbnail(ObClient *self, gint wantw, gint wanth)
-{
-    ObClientIcon *ret;
-    RrPixel32 *data;
-    gint w, h;
-
-    if (!self->frame->pixmap) return NULL;
-    if (!RrPixmapToRGBA(ob_rr_inst, self->frame->pixmap, None, &w, &h, &data))
-        return NULL;
-
-    /* resize the thumbnail (within aspect ratio) to the given sizes */
-
-    ret = g_new(ObClientIcon, 1);
-    ret->data = data;
-    ret->width = w;
-    ret->height = h;
-    return ret;
-}
-
-void clienticon_free(ObClientIcon *ci)
-{
-    if (ci) {
-        g_free(ci->data);
-        g_free(ci);
-    }
-}
This page took 0.029586 seconds and 4 git commands to generate.