]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
adding trunk
[chaz/openbox] / openbox / client.c
index 820249451adba32423eade64d845e1d39523b277..071ecc4d7b262392bf25890e4965b3a6f3ede687 100644 (file)
@@ -274,6 +274,9 @@ void client_manage(Window window)
     /* get all the stuff off the window */
     client_get_all(self, TRUE);
 
+    ob_debug("Window type: %d\n", self->type);
+    ob_debug("Window group: 0x%x\n", self->group?self->group->leader:0);
+
     /* specify that if we exit, the window should not be destroyed and
        should be reparented back to root automatically */
     XChangeSaveSet(ob_display, window, SetModeInsert);
@@ -320,7 +323,7 @@ void client_manage(Window window)
          client_search_focus_tree_full(self)) &&
         /* this checks for focus=false for the window */
         (!settings || settings->focus != 0) &&
-        focus_valid_target(self, FALSE, TRUE, FALSE, FALSE))
+        focus_valid_target(self, FALSE, FALSE, TRUE, FALSE, FALSE))
     {
         activate = TRUE;
     }
@@ -1278,88 +1281,45 @@ static void client_update_transient_tree(ObClient *self,
         oldgtran == newgtran &&
         oldparent == newparent) return;
 
-    /** Remove the client from the transient tree wherever it has changed **/
-
-    /* If the window is becoming a direct transient for a window in its group
-       then any group transients which were our children and are now becoming
-       our parents need to stop being our children.
+    /** Remove the client from the transient tree **/
 
-       Group transients can't be children of group transients already, but
-       we could have any number of direct parents above up, any of which could
-       be transient for the group, and we need to remove it from our children.
-    */
-    if (!oldgtran && oldparent != newparent && newparent != NULL &&
-        newgroup != NULL && newgroup == oldgroup &&
-        client_normal(newparent))
-    {
-        ObClient *look = client_search_top_direct_parent(newparent);
-        self->transients = g_slist_remove(self->transients, look);
-        look->parents = g_slist_remove(look->parents, self);
+    for (it = self->transients; it; it = next) {
+        next = g_slist_next(it);
+        c = it->data;
+        self->transients = g_slist_delete_link(self->transients, it);
+        c->parents = g_slist_remove(c->parents, self);
     }
-            
-
-    /* If the group changed, or if we are just becoming transient for the
-       group, then we need to remove any old group transient windows
-       from our children. But if we were already transient for the group, then
-       other group transients are not our children. */
-    if ((oldgroup != newgroup || (newgtran && oldgtran != newgtran)) &&
-        oldgroup != NULL && !oldgtran)
-    {
-        for (it = self->transients; it; it = next) {
-            next = g_slist_next(it);
-            c = it->data;
-            if (c->group == oldgroup && client_normal(self)) {
-                self->transients = g_slist_delete_link(self->transients, it);
-                c->parents = g_slist_remove(c->parents, self);
-            }
-        }
+    for (it = self->parents; it; it = next) {
+        next = g_slist_next(it);
+        c = it->data;
+        self->parents = g_slist_delete_link(self->parents, it);
+        c->transients = g_slist_remove(c->transients, self);
     }
 
-    /* If we used to be transient for a group and now we are not, or we're
-       transient for a new group, then we need to remove ourselves from all
-       our ex-parents */
-    if (oldgtran && (oldgroup != newgroup || oldgtran != newgtran))
-    {
-        for (it = self->parents; it; it = next) {
-            next = g_slist_next(it);
-            c = it->data;
-            if (!c->transient_for_group && client_normal(c)) {
-                c->transients = g_slist_remove(c->transients, self);
-                self->parents = g_slist_delete_link(self->parents, it);
-            }
-        }
-    }
-    /* If we used to be transient for a single window and we are no longer
-       transient for it, then we need to remove ourself from its children */
-    else if (oldparent && oldparent != newparent &&
-             client_normal(oldparent))
-    {
-        oldparent->transients = g_slist_remove(oldparent->transients, self);
-        self->parents = g_slist_remove(self->parents, oldparent);
-    }
+    /** Re-add the client to the transient tree **/
 
-    /** Re-add the client to the transient tree wherever it has changed **/
-
-    /* If we're now transient for a group and we weren't transient for it
-       before then we need to add ourselves to all our new parents */
-    if (newgtran && (oldgroup != newgroup || oldgtran != newgtran))
-    {
-        for (it = oldgroup->members; it; it = g_slist_next(it)) {
+    /* If we're transient for a group then we need to add ourselves to all our
+       parents */
+    if (newgtran) {
+        for (it = newgroup->members; it; it = g_slist_next(it)) {
             c = it->data;
-            if (c != self && !c->transient_for_group && client_normal(c))
+            if (c != self &&
+                !client_search_top_direct_parent(c)->transient_for_group &&
+                client_normal(c))
             {
                 c->transients = g_slist_prepend(c->transients, self);
                 self->parents = g_slist_prepend(self->parents, c);
             }
         }
     }
-    /* If we are now transient for a single window which we weren't before,
-       we need to add ourselves to its children
+
+    /* If we are now transient for a single window we need to add ourselves to
+       its children
 
        WARNING: Cyclical transient ness is possible if two windows are
        transient for eachother.
     */
-    else if (newparent && newparent != oldparent &&
+    else if (newparent &&
              /* don't make ourself its child if it is already our child */
              !client_is_direct_child(self, newparent) &&
              client_normal(newparent))
@@ -1368,9 +1328,8 @@ static void client_update_transient_tree(ObClient *self,
         self->parents = g_slist_prepend(self->parents, newparent);
     }
 
-    /* If the group changed then we need to add any new group transient
-       windows to our children. But if we're transient for the group, then
-       other group transients are not our children.
+    /* Add any group transient windows to our children. But if we're transient
+       for the group, then other group transients are not our children.
 
        WARNING: Cyclical transient-ness is possible. For e.g. if:
        A is transient for the group
@@ -1378,7 +1337,9 @@ 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 (oldgroup != newgroup && newgroup != NULL && !newgtran &&
+    if (!newgtran &&
+        (!newparent ||
+         !client_search_top_direct_parent(newparent)->transient_for_group) &&
         client_normal(self))
     {
         for (it = newgroup->members; it; it = g_slist_next(it)) {
@@ -1392,6 +1353,20 @@ static void client_update_transient_tree(ObClient *self,
             }
         }
     }
+
+    /** If we change our group transient-ness, our children change their
+        effect group transient-ness, which affects how they relate to other
+        group windows **/
+
+    for (it = self->transients; it; it = g_slist_next(it)) {
+        c = it->data;
+        if (!c->transient_for_group)
+            client_update_transient_tree(c, c->group, c->group,
+                                         c->transient_for_group,
+                                         c->transient_for_group,
+                                         client_direct_parent(c),
+                                         client_direct_parent(c));
+    }
 }
 
 static void client_get_mwm_hints(ObClient *self)
@@ -2891,9 +2866,6 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h,
     oldw = self->area.width;
     oldh = self->area.height;
     RECT_SET(self->area, x, y, w, h);
-    ob_debug("Client area %s set to %d %d %d %d\n",
-             self->title, self->area.x, self->area.y,
-             self->area.width, self->area.height);
 
     /* for app-requested resizes, always resize if 'resized' is true.
        for user-requested ones, only resize if final is true, or when
@@ -3877,188 +3849,297 @@ ObClient *client_search_transient(ObClient *self, ObClient *search)
     return NULL;
 }
 
-#define WANT_EDGE(cur, c) \
-            if (cur == c)                                                     \
-                continue;                                                     \
-            if (c->desktop != cur->desktop && cur->desktop != DESKTOP_ALL &&  \
-                cur->desktop != screen_desktop)                               \
-                continue;                                                     \
-            if (cur->iconic)                                                  \
-                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, gboolean hang)
+void client_find_edge_directional(ObClient *self, ObDirection dir,
+                                  gint my_head, gint my_size,
+                                  gint my_edge_start, gint my_edge_size,
+                                  gint *dest, gboolean *near_edge)
 {
-    gint dest, monitor_dest;
-    gint my_edge_start, my_edge_end, my_offset;
     GList *it;
     Rect *a, *mon;
-    
-    if(!client_list)
-        return -1;
+    gint edge;
 
-    a = screen_area(c->desktop, SCREEN_AREA_ALL_MONITORS, &c->frame->area);
-    mon = screen_area(c->desktop, SCREEN_AREA_ONE_MONITOR, &c->frame->area);
+    a = screen_area(self->desktop, SCREEN_AREA_ALL_MONITORS,
+                    &self->frame->area);
+    mon = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR,
+                      &self->frame->area);
 
     switch(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 + (hang ? c->frame->area.height : 0);
-        
-        /* default: top of screen */
-        dest = a->y + (hang ? c->frame->area.height : 0);
-        monitor_dest = mon->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)
-            dest = monitor_dest; 
-
-        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;
-
-            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 + 
-                         (hang ? 0 : cur->frame->area.height);
-
-            if(his_offset + 1 > my_offset)
-                continue;
-
-            if(his_offset < dest)
-                continue;
-
-            HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end)
-        }
+        if (my_head >= RECT_TOP(*mon))
+            edge = RECT_TOP(*mon) - 1;
+        else
+            edge = RECT_TOP(*a) - 1;
         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 + (hang ? 0 : c->frame->area.height);
-
-        /* default: bottom of screen */
-        dest = a->y + a->height - (hang ? c->frame->area.height : 0);
-        monitor_dest = mon->y + mon->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)
-            dest = monitor_dest; 
+        if (my_head <= RECT_BOTTOM(*mon))
+            edge = RECT_BOTTOM(*mon) + 1;
+        else
+            edge = RECT_BOTTOM(*a) + 1;
+        break;
+    case OB_DIRECTION_EAST:
+        if (my_head <= RECT_RIGHT(*mon))
+            edge = RECT_RIGHT(*mon) + 1;
+        else
+            edge = RECT_RIGHT(*a) + 1;
+        break;
+    case OB_DIRECTION_WEST:
+        if (my_head >= RECT_LEFT(*mon))
+            edge = RECT_LEFT(*mon) - 1;
+        else
+            edge = RECT_LEFT(*a) - 1;
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    /* default to the far edge, then narrow it down */
+    *dest = edge;
+    *near_edge = TRUE;
 
-        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;
+    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;
 
-            WANT_EDGE(cur, c)
+        /* skip windows to not bump into */
+        if (cur == self)
+            continue;
+        if (cur->iconic)
+            continue;
+        if (self->desktop != cur->desktop && cur->desktop != DESKTOP_ALL &&
+            cur->desktop != screen_desktop)
+            continue;
 
-            his_edge_start = cur->frame->area.x;
-            his_edge_end = cur->frame->area.x + cur->frame->area.width;
-            his_offset = cur->frame->area.y +
-                         (hang ? cur->frame->area.height : 0);
+        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();
+        }
 
-            if(his_offset - 1 < my_offset)
-                continue;
-            
-            if(his_offset > dest)
-                continue;
+        /* do we collide with this window? */
+        if (!RANGES_INTERSECT(my_edge_start, my_edge_size,
+                              edge_start, edge_size))
+            continue;
 
-            HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end)
+        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();
         }
-        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 + (hang ? c->frame->area.width : 0);
 
-        /* default: leftmost egde of screen */
-        dest = a->x + (hang ? c->frame->area.width : 0);
-        monitor_dest = mon->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)
-            dest = monitor_dest;            
+        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();
+        }
 
-        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;
+        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;
+        }
+    }
+}
 
-            WANT_EDGE(cur, c)
+void client_find_move_directional(ObClient *self, ObDirection dir,
+                                  gint *x, gint *y)
+{
+    gint head, size;
+    gint e, e_start, e_size;
+    gboolean near;
 
-            his_edge_start = cur->frame->area.y;
-            his_edge_end = cur->frame->area.y + cur->frame->area.height;
-            his_offset = cur->frame->area.x +
-                         (hang ? 0 : cur->frame->area.width);
+    switch (dir) {
+    case OB_DIRECTION_EAST:
+        head = RECT_RIGHT(self->frame->area);
+        size = self->frame->area.width;
+        e_start = RECT_TOP(self->frame->area);
+        e_size = self->frame->area.height;
+        break;
+    case OB_DIRECTION_WEST:
+        head = RECT_LEFT(self->frame->area);
+        size = self->frame->area.width;
+        e_start = RECT_TOP(self->frame->area);
+        e_size = self->frame->area.height;
+        break;
+    case OB_DIRECTION_NORTH:
+        head = RECT_TOP(self->frame->area);
+        size = self->frame->area.height;
+        e_start = RECT_LEFT(self->frame->area);
+        e_size = self->frame->area.width;
+        break;
+    case OB_DIRECTION_SOUTH:
+        head = RECT_BOTTOM(self->frame->area);
+        size = self->frame->area.height;
+        e_start = RECT_LEFT(self->frame->area);
+        e_size = self->frame->area.width;
+        break;
+    default:
+        g_assert_not_reached();
+    }
 
-            if(his_offset + 1 > my_offset)
-                continue;
+    client_find_edge_directional(self, dir, head, size,
+                                 e_start, e_size, &e, &near);
+    *x = self->frame->area.x;
+    *y = self->frame->area.y;
+    switch (dir) {
+    case OB_DIRECTION_EAST:
+        if (near) e -= self->frame->area.width;
+        else      e++;
+        *x = e;
+        break;
+    case OB_DIRECTION_WEST:
+        if (near) e++;
+        else      e -= self->frame->area.width;
+        *x = e;
+        break;
+    case OB_DIRECTION_NORTH:
+        if (near) e++;
+        else      e -= self->frame->area.height;
+        *y = e;
+        break;
+    case OB_DIRECTION_SOUTH:
+        if (near) e -= self->frame->area.height;
+        else      e++;
+        *y = e;
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    frame_frame_gravity(self->frame, x, y);
+}
 
-            if(his_offset < dest)
-                continue;
+void client_find_resize_directional(ObClient *self, ObDirection side,
+                                    gboolean grow,
+                                    gint *x, gint *y, gint *w, gint *h)
+{
+    gint head;
+    gint e, e_start, e_size, delta;
+    gboolean near;
+    ObDirection dir;
 
-            HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end)
-        }
-       break;
+    switch (side) {
     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 + (hang ? 0 : c->frame->area.width);
-        
-        /* default: rightmost edge of screen */
-        dest = a->x + a->width - (hang ? c->frame->area.width : 0);
-        monitor_dest = mon->x + mon->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)
-            dest = monitor_dest;            
-
-        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;
-
-            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 +
-                         (hang ? cur->frame->area.width : 0);
-
-            if(his_offset - 1 < my_offset)
-                continue;
-            
-            if(his_offset > dest)
-                continue;
-
-            HIT_EDGE(my_edge_start, my_edge_end, his_edge_start, his_edge_end)
-        }
+        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) * (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) * (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) * (grow ? 1 : -1);
+        e_start = RECT_LEFT(self->frame->area);
+        e_size = self->frame->area.width;
+        dir = grow ? OB_DIRECTION_SOUTH : OB_DIRECTION_NORTH;
         break;
-    case OB_DIRECTION_NORTHEAST:
-    case OB_DIRECTION_SOUTHEAST:
-    case OB_DIRECTION_NORTHWEST:
-    case OB_DIRECTION_SOUTHWEST:
-        /* not implemented */
     default:
         g_assert_not_reached();
-        dest = 0; /* suppress warning */
     }
 
-    g_free(a);
-    g_free(mon);
-    return dest;
+    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 (grow == near) --e;
+        delta = e - RECT_RIGHT(self->frame->area);
+        *w += delta;
+        break;
+    case OB_DIRECTION_WEST:
+        if (grow == near) ++e;
+        delta = RECT_LEFT(self->frame->area) - e;
+        *x -= delta;
+        *w += delta;
+        break;
+    case OB_DIRECTION_NORTH:
+        if (grow == near) ++e;
+        delta = RECT_TOP(self->frame->area) - e;
+        *y -= delta;
+        *h += delta;
+        break;
+    case OB_DIRECTION_SOUTH:
+        if (grow == near) --e;
+        delta = e - RECT_BOTTOM(self->frame->area);
+        *h += delta;
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    frame_frame_gravity(self->frame, x, y);
+    *w -= self->frame->size.left + self->frame->size.right;
+    *h -= self->frame->size.top + self->frame->size.bottom;
 }
 
 ObClient* client_under_pointer()
@@ -4094,30 +4175,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.038905 seconds and 4 git commands to generate.