]> git.sur5r.net Git - i3/i3/blobdiff - src/con.c
Bugfix: don’t overwrite the original size of floating windows when changing border...
[i3/i3] / src / con.c
index fe26d6945ec2553f10b5217acb982836198d136f..14948cc6c2155eb40874f1b494cf0fd3b7540913 100644 (file)
--- a/src/con.c
+++ b/src/con.c
@@ -51,6 +51,7 @@ Con *con_new_skeleton(Con *parent, i3Window *window) {
     Con *new = scalloc(sizeof(Con));
     new->on_remove_child = con_on_remove_child;
     TAILQ_INSERT_TAIL(&all_cons, new, all_cons);
+    new->aspect_ratio = 0.0;
     new->type = CT_CON;
     new->window = window;
     new->border_style = config.default_border;
@@ -240,6 +241,17 @@ bool con_is_leaf(Con *con) {
     return TAILQ_EMPTY(&(con->nodes_head));
 }
 
+/*
+ * Returns true when this con is a leaf node with a managed X11 window (e.g.,
+ * excluding dock containers)
+ */
+bool con_has_managed_window(Con *con) {
+    return (con != NULL
+            && con->window != NULL
+            && con->window->id != XCB_WINDOW_NONE
+            && con_get_workspace(con) != NULL);
+}
+
 /**
  * Returns true if this node has regular or floating children.
  *
@@ -352,7 +364,7 @@ struct bfs_entry {
  * Returns the first fullscreen node below this node.
  *
  */
-Con *con_get_fullscreen_con(Con *con, int fullscreen_mode) {
+Con *con_get_fullscreen_con(Con *con, fullscreen_mode_t fullscreen_mode) {
     Con *current, *child;
 
     /* TODO: is breadth-first-search really appropriate? (check as soon as
@@ -568,8 +580,9 @@ void con_fix_percent(Con *con) {
 }
 
 /*
- * Toggles fullscreen mode for the given container. Fullscreen mode will not be
- * entered when there already is a fullscreen container on this workspace.
+ * Toggles fullscreen mode for the given container. If there already is a
+ * fullscreen container on this workspace, fullscreen will be disabled and then
+ * enabled for the container the user wants to have in fullscreen mode.
  *
  */
 void con_toggle_fullscreen(Con *con, int fullscreen_mode) {
@@ -607,6 +620,9 @@ void con_toggle_fullscreen(Con *con, int fullscreen_mode) {
 
     DLOG("mode now: %d\n", con->fullscreen_mode);
 
+    /* Send an ipc window "fullscreen_mode" event */
+    ipc_send_window_event("fullscreen_mode", con);
+
     /* update _NET_WM_STATE if this container has a window */
     /* TODO: when a window is assigned to a container which is already
      * fullscreened, this state needs to be pushed to the client, too */
@@ -824,7 +840,7 @@ void con_move_to_workspace(Con *con, Con *workspace, bool fix_coordinates, bool
  * container).
  *
  */
-int con_orientation(Con *con) {
+orientation_t con_orientation(Con *con) {
     switch (con->layout) {
         case L_SPLITV:
         /* stacking containers behave like they are in vertical orientation */
@@ -1074,8 +1090,13 @@ Rect con_border_style_rect(Con *con) {
     int border_width = con->current_border_width;
     DLOG("The border width for con is set to: %d\n", con->current_border_width);
     Rect result;
-    if (con->current_border_width < 0)
-        border_width = config.default_border_width;
+    if (con->current_border_width < 0) {
+        if (con_is_floating(con)) {
+            border_width = config.default_floating_border_width;
+        } else {
+            border_width = config.default_border_width;
+        }
+    }
     DLOG("Effective border width is set to: %d\n", border_width);
     /* Shortcut to avoid calling con_adjacent_borders() on dock containers. */
     int border_style = con_border_style(con);
@@ -1173,34 +1194,30 @@ void con_set_border_style(Con *con, int border_style, int border_width) {
 
     /* For floating containers, we want to keep the position/size of the
      * *window* itself. We first add the border pixels to con->rect to make
-     * con->rect represent the absolute position of the window. Then, we change
-     * the border and subtract the new border pixels. Afterwards, we update
-     * parent->rect to contain con. */
+     * con->rect represent the absolute position of the window (same for
+     * parent). Then, we change the border style and subtract the new border
+     * pixels. For the parent, we do the same also for the decoration. */
     DLOG("This is a floating container\n");
 
+    Con *parent = con->parent;
     Rect bsr = con_border_style_rect(con);
-    con->rect.x += bsr.x;
-    con->rect.y += bsr.y;
-    con->rect.width += bsr.width;
-    con->rect.height += bsr.height;
+    int deco_height = (con->border_style == BS_NORMAL ? render_deco_height() : 0);
+
+    con->rect = rect_add(con->rect, bsr);
+    parent->rect = rect_add(parent->rect, bsr);
+    parent->rect.y += deco_height;
+    parent->rect.height -= deco_height;
 
     /* Change the border style, get new border/decoration values. */
     con->border_style = border_style;
     con->current_border_width = border_width;
     bsr = con_border_style_rect(con);
-    int deco_height =
-        (con->border_style == BS_NORMAL ? render_deco_height() : 0);
+    deco_height = (con->border_style == BS_NORMAL ? render_deco_height() : 0);
 
-    con->rect.x -= bsr.x;
-    con->rect.y -= bsr.y;
-    con->rect.width -= bsr.width;
-    con->rect.height -= bsr.height;
-
-    Con *parent = con->parent;
-    parent->rect.x = con->rect.x;
-    parent->rect.y = con->rect.y - deco_height;
-    parent->rect.width = con->rect.width;
-    parent->rect.height = con->rect.height + deco_height;
+    con->rect = rect_sub(con->rect, bsr);
+    parent->rect = rect_sub(parent->rect, bsr);
+    parent->rect.y -= deco_height;
+    parent->rect.height += deco_height;
 }
 
 /*
@@ -1353,8 +1370,9 @@ static void con_on_remove_child(Con *con) {
      * not be closed when the last child was removed */
     if (con->type == CT_OUTPUT ||
         con->type == CT_ROOT ||
-        con->type == CT_DOCKAREA) {
-        DLOG("not handling, type = %d\n", con->type);
+        con->type == CT_DOCKAREA ||
+        (con->parent != NULL && con->parent->type == CT_OUTPUT)) {
+        DLOG("not handling, type = %d, name = %s\n", con->type, con->name);
         return;
     }
 
@@ -1369,6 +1387,8 @@ static void con_on_remove_child(Con *con) {
     }
 
     con_force_split_parents_redraw(con);
+    con->urgent = con_has_urgent_child(con);
+    con_update_parents_urgency(con);
 
     /* TODO: check if this container would swallow any other client and
      * don’t close it automatically. */