]> git.sur5r.net Git - i3/i3/commitdiff
Merge pull request #3368 from orestisf1993/render_root
authorIngo Bürk <admin@airblader.de>
Fri, 24 Aug 2018 07:49:41 +0000 (09:49 +0200)
committerGitHub <noreply@github.com>
Fri, 24 Aug 2018 07:49:41 +0000 (09:49 +0200)
(floating) global fullscreen bugs & others

1  2 
src/commands.c
src/handlers.c
src/render.c

diff --combined src/commands.c
index 0874eec2346c12c753e31e6aacf09af43f8c0aac,22ec6c3fa9ca54d84ee15ede02cf223351b9abe4..0343f9dc3525f9a68366f1b0839fde9a764a48f5
@@@ -419,104 -419,110 +419,104 @@@ void cmd_move_con_to_workspace_number(I
      ysuccess(true);
  }
  
 -static void cmd_resize_floating(I3_CMD, const char *way, const char *direction, Con *floating_con, int px) {
 -    LOG("floating resize\n");
 +/*
 + * Convert a string direction ("left", "right", etc.) to a direction_t. Assumes
 + * valid direction string.
 + */
 +static direction_t parse_direction(const char *str) {
 +    if (strcmp(str, "left") == 0) {
 +        return D_LEFT;
 +    } else if (strcmp(str, "right") == 0) {
 +        return D_RIGHT;
 +    } else if (strcmp(str, "up") == 0) {
 +        return D_UP;
 +    } else if (strcmp(str, "down") == 0) {
 +        return D_DOWN;
 +    } else {
 +        ELOG("Invalid direction. This is a parser bug.\n");
 +        assert(false);
 +    }
 +}
 +
 +static void cmd_resize_floating(I3_CMD, const char *way, const char *direction_str, Con *floating_con, int px) {
      Rect old_rect = floating_con->rect;
      Con *focused_con = con_descend_focused(floating_con);
  
 +    direction_t direction;
 +    if (strcmp(direction_str, "height") == 0) {
 +        direction = D_DOWN;
 +    } else if (strcmp(direction_str, "width") == 0) {
 +        direction = D_RIGHT;
 +    } else {
 +        direction = parse_direction(direction_str);
 +    }
 +    orientation_t orientation = orientation_from_direction(direction);
 +
      /* ensure that resize will take place even if pixel increment is smaller than
       * height increment or width increment.
       * fixes #1011 */
      const i3Window *window = focused_con->window;
      if (window != NULL) {
 -        if (strcmp(direction, "up") == 0 || strcmp(direction, "down") == 0 ||
 -            strcmp(direction, "height") == 0) {
 -            if (px < 0)
 +        if (orientation == VERT) {
 +            if (px < 0) {
                  px = (-px < window->height_increment) ? -window->height_increment : px;
 -            else
 +            } else {
                  px = (px < window->height_increment) ? window->height_increment : px;
 -        } else if (strcmp(direction, "left") == 0 || strcmp(direction, "right") == 0) {
 -            if (px < 0)
 +            }
 +        } else {
 +            if (px < 0) {
                  px = (-px < window->width_increment) ? -window->width_increment : px;
 -            else
 +            } else {
                  px = (px < window->width_increment) ? window->width_increment : px;
 +            }
          }
      }
  
 -    if (strcmp(direction, "up") == 0) {
 +    if (orientation == VERT) {
          floating_con->rect.height += px;
 -    } else if (strcmp(direction, "down") == 0 || strcmp(direction, "height") == 0) {
 -        floating_con->rect.height += px;
 -    } else if (strcmp(direction, "left") == 0) {
 -        floating_con->rect.width += px;
      } else {
          floating_con->rect.width += px;
      }
 -
      floating_check_size(floating_con);
  
      /* Did we actually resize anything or did the size constraints prevent us?
       * If we could not resize, exit now to not move the window. */
 -    if (memcmp(&old_rect, &(floating_con->rect), sizeof(Rect)) == 0)
 +    if (memcmp(&old_rect, &(floating_con->rect), sizeof(Rect)) == 0) {
          return;
 +    }
  
 -    if (strcmp(direction, "up") == 0) {
 +    if (direction == D_UP) {
          floating_con->rect.y -= (floating_con->rect.height - old_rect.height);
 -    } else if (strcmp(direction, "left") == 0) {
 +    } else if (direction == D_LEFT) {
          floating_con->rect.x -= (floating_con->rect.width - old_rect.width);
      }
  
      /* If this is a scratchpad window, don't auto center it from now on. */
 -    if (floating_con->scratchpad_state == SCRATCHPAD_FRESH)
 +    if (floating_con->scratchpad_state == SCRATCHPAD_FRESH) {
          floating_con->scratchpad_state = SCRATCHPAD_CHANGED;
 +    }
  }
  
 -static bool cmd_resize_tiling_direction(I3_CMD, Con *current, const char *way, const char *direction, int ppt) {
 -    LOG("tiling resize\n");
 +static bool cmd_resize_tiling_direction(I3_CMD, Con *current, const char *direction, int px, int ppt) {
      Con *second = NULL;
      Con *first = current;
 -    direction_t search_direction;
 -    if (!strcmp(direction, "left"))
 -        search_direction = D_LEFT;
 -    else if (!strcmp(direction, "right"))
 -        search_direction = D_RIGHT;
 -    else if (!strcmp(direction, "up"))
 -        search_direction = D_UP;
 -    else
 -        search_direction = D_DOWN;
 +    direction_t search_direction = parse_direction(direction);
  
      bool res = resize_find_tiling_participants(&first, &second, search_direction, false);
      if (!res) {
 -        LOG("No second container in this direction found.\n");
 -        ysuccess(false);
 +        yerror("No second container found in this direction.\n");
          return false;
      }
  
 -    /* get the default percentage */
 -    int children = con_num_children(first->parent);
 -    LOG("ins. %d children\n", children);
 -    double percentage = 1.0 / children;
 -    LOG("default percentage = %f\n", percentage);
 -
 -    /* resize */
 -    LOG("first->percent before = %f\n", first->percent);
 -    LOG("second->percent before = %f\n", second->percent);
 -    if (first->percent == 0.0)
 -        first->percent = percentage;
 -    if (second->percent == 0.0)
 -        second->percent = percentage;
 -    double new_first_percent = first->percent + ((double)ppt / 100.0);
 -    double new_second_percent = second->percent - ((double)ppt / 100.0);
 -    LOG("new_first_percent = %f\n", new_first_percent);
 -    LOG("new_second_percent = %f\n", new_second_percent);
 -    /* Ensure that the new percentages are positive. */
 -    if (new_first_percent > 0.0 && new_second_percent > 0.0) {
 -        first->percent = new_first_percent;
 -        second->percent = new_second_percent;
 -        LOG("first->percent after = %f\n", first->percent);
 -        LOG("second->percent after = %f\n", second->percent);
 -    } else {
 -        LOG("Not resizing, already at minimum size\n");
 +    if (ppt) {
 +        /* For backwards compatibility, 'X px or Y ppt' means that ppt is
 +         * preferred. */
 +        px = 0;
      }
 -
 -    return true;
 +    return resize_neighboring_cons(first, second, px, ppt);
  }
  
 -static bool cmd_resize_tiling_width_height(I3_CMD, Con *current, const char *way, const char *direction, int ppt) {
 +static bool cmd_resize_tiling_width_height(I3_CMD, Con *current, const char *direction, int px, double ppt) {
      LOG("width/height resize\n");
  
      /* get the appropriate current container (skip stacked/tabbed cons) */
              child->percent = percentage;
      }
  
 -    double new_current_percent = current->percent + ((double)ppt / 100.0);
 -    double subtract_percent = ((double)ppt / 100.0) / (children - 1);
 +    double new_current_percent;
 +    double subtract_percent;
 +    if (ppt != 0.0) {
 +        new_current_percent = current->percent + ppt;
 +    } else {
 +        new_current_percent = px_resize_to_percent(current, px);
 +        ppt = new_current_percent - current->percent;
 +    }
 +    subtract_percent = ppt / (children - 1);
 +
      LOG("new_current_percent = %f\n", new_current_percent);
      LOG("subtract_percent = %f\n", subtract_percent);
      /* Ensure that the new percentages are positive. */
@@@ -610,15 -608,12 +610,15 @@@ void cmd_resize(I3_CMD, const char *way
          } else {
              if (strcmp(direction, "width") == 0 ||
                  strcmp(direction, "height") == 0) {
 +                const double ppt = (double)resize_ppt / 100.0;
                  if (!cmd_resize_tiling_width_height(current_match, cmd_output,
 -                                                    current->con, way, direction, resize_ppt))
 +                                                    current->con, direction,
 +                                                    resize_px, ppt))
                      return;
              } else {
                  if (!cmd_resize_tiling_direction(current_match, cmd_output,
 -                                                 current->con, way, direction, resize_ppt))
 +                                                 current->con, direction,
 +                                                 resize_px, resize_ppt))
                      return;
              }
          }
      ysuccess(true);
  }
  
 +static bool resize_set_tiling(I3_CMD, Con *target, orientation_t resize_orientation, bool is_ppt, long target_size) {
 +    direction_t search_direction;
 +    char *mode;
 +    if (resize_orientation == HORIZ) {
 +        search_direction = D_LEFT;
 +        mode = "width";
 +    } else {
 +        search_direction = D_DOWN;
 +        mode = "height";
 +    }
 +
 +    /* Get the appropriate current container (skip stacked/tabbed cons) */
 +    Con *dummy;
 +    resize_find_tiling_participants(&target, &dummy, search_direction, true);
 +
 +    /* Calculate new size for the target container */
 +    double ppt = 0.0;
 +    int px = 0;
 +    if (is_ppt) {
 +        ppt = (double)target_size / 100.0 - target->percent;
 +    } else {
 +        px = target_size - (resize_orientation == HORIZ ? target->rect.width : target->rect.height);
 +    }
 +
 +    /* Perform resizing and report failure if not possible */
 +    return cmd_resize_tiling_width_height(current_match, cmd_output,
 +                                          target, mode, px, ppt);
 +}
 +
  /*
   * Implementation of 'resize set <width> [px | ppt] <height> [px | ppt]'.
   *
@@@ -694,13 -660,56 +694,13 @@@ void cmd_resize_set(I3_CMD, long cwidth
                  continue;
              }
  
 -            if (cwidth > 0 && mode_width && strcmp(mode_width, "ppt") == 0) {
 -                /* get the appropriate current container (skip stacked/tabbed cons) */
 -                Con *target = current->con;
 -                Con *dummy;
 -                resize_find_tiling_participants(&target, &dummy, D_LEFT, true);
 -
 -                /* Calculate new size for the target container */
 -                double current_percent = target->percent;
 -                char *action_string;
 -                long adjustment;
 -
 -                if (current_percent > cwidth) {
 -                    action_string = "shrink";
 -                    adjustment = (int)(current_percent * 100) - cwidth;
 -                } else {
 -                    action_string = "grow";
 -                    adjustment = cwidth - (int)(current_percent * 100);
 -                }
 -
 -                /* perform resizing and report failure if not possible */
 -                if (!cmd_resize_tiling_width_height(current_match, cmd_output,
 -                                                    target, action_string, "width", adjustment)) {
 -                    success = false;
 -                }
 +            if (cwidth > 0 && mode_width) {
 +                success &= resize_set_tiling(current_match, cmd_output, current->con,
 +                                             HORIZ, strcmp(mode_width, "ppt") == 0, cwidth);
              }
 -
 -            if (cheight > 0 && mode_height && strcmp(mode_height, "ppt") == 0) {
 -                /* get the appropriate current container (skip stacked/tabbed cons) */
 -                Con *target = current->con;
 -                Con *dummy;
 -                resize_find_tiling_participants(&target, &dummy, D_DOWN, true);
 -
 -                /* Calculate new size for the target container */
 -                double current_percent = target->percent;
 -                char *action_string;
 -                long adjustment;
 -
 -                if (current_percent > cheight) {
 -                    action_string = "shrink";
 -                    adjustment = (int)(current_percent * 100) - cheight;
 -                } else {
 -                    action_string = "grow";
 -                    adjustment = cheight - (int)(current_percent * 100);
 -                }
 -
 -                /* perform resizing and report failure if not possible */
 -                if (!cmd_resize_tiling_width_height(current_match, cmd_output,
 -                                                    target, action_string, "height", adjustment)) {
 -                    success = false;
 -                }
 +            if (cheight > 0 && mode_height) {
 +                success &= resize_set_tiling(current_match, cmd_output, current->con,
 +                                             VERT, strcmp(mode_height, "ppt") == 0, cheight);
              }
          }
      }
@@@ -1245,19 -1254,20 +1245,19 @@@ void cmd_exec(I3_CMD, const char *nosn
   *
   */
  void cmd_focus_direction(I3_CMD, const char *direction) {
 -    DLOG("direction = *%s*\n", direction);
 -
 -    if (strcmp(direction, "left") == 0)
 -        tree_next('p', HORIZ);
 -    else if (strcmp(direction, "right") == 0)
 -        tree_next('n', HORIZ);
 -    else if (strcmp(direction, "up") == 0)
 -        tree_next('p', VERT);
 -    else if (strcmp(direction, "down") == 0)
 -        tree_next('n', VERT);
 -    else {
 -        ELOG("Invalid focus direction (%s)\n", direction);
 -        ysuccess(false);
 -        return;
 +    switch (parse_direction(direction)) {
 +        case D_LEFT:
 +            tree_next('p', HORIZ);
 +            break;
 +        case D_RIGHT:
 +            tree_next('n', HORIZ);
 +            break;
 +        case D_UP:
 +            tree_next('p', VERT);
 +            break;
 +        case D_DOWN:
 +            tree_next('n', VERT);
 +            break;
      }
  
      cmd_output->needs_tree_render = true;
  static void cmd_focus_force_focus(Con *con) {
      /* Disable fullscreen container in workspace with container to be focused. */
      Con *ws = con_get_workspace(con);
-     Con *fullscreen_on_ws = (focused && focused->fullscreen_mode == CF_GLOBAL) ? focused : con_get_fullscreen_con(ws, CF_OUTPUT);
+     Con *fullscreen_on_ws = con_get_fullscreen_covering_ws(ws);
      if (fullscreen_on_ws && fullscreen_on_ws != con && !con_has_parent(con, fullscreen_on_ws)) {
          con_disable_fullscreen(fullscreen_on_ws);
      }
@@@ -1482,37 -1492,29 +1482,37 @@@ void cmd_sticky(I3_CMD, const char *act
   * Implementation of 'move <direction> [<pixels> [px]]'.
   *
   */
 -void cmd_move_direction(I3_CMD, const char *direction, long move_px) {
 +void cmd_move_direction(I3_CMD, const char *direction_str, long move_px) {
      owindow *current;
      HANDLE_EMPTY_MATCH;
  
      Con *initially_focused = focused;
 +    direction_t direction = parse_direction(direction_str);
  
      TAILQ_FOREACH(current, &owindows, owindows) {
 -        DLOG("moving in direction %s, px %ld\n", direction, move_px);
 +        DLOG("moving in direction %s, px %ld\n", direction_str, move_px);
          if (con_is_floating(current->con)) {
              DLOG("floating move with %ld pixels\n", move_px);
              Rect newrect = current->con->parent->rect;
 -            if (strcmp(direction, "left") == 0) {
 -                newrect.x -= move_px;
 -            } else if (strcmp(direction, "right") == 0) {
 -                newrect.x += move_px;
 -            } else if (strcmp(direction, "up") == 0) {
 -                newrect.y -= move_px;
 -            } else if (strcmp(direction, "down") == 0) {
 -                newrect.y += move_px;
 +
 +            switch (direction) {
 +                case D_LEFT:
 +                    newrect.x -= move_px;
 +                    break;
 +                case D_RIGHT:
 +                    newrect.x += move_px;
 +                    break;
 +                case D_UP:
 +                    newrect.y -= move_px;
 +                    break;
 +                case D_DOWN:
 +                    newrect.y += move_px;
 +                    break;
              }
 +
              floating_reposition(current->con->parent, newrect);
          } else {
 -            tree_move(current->con, (strcmp(direction, "right") == 0 ? D_RIGHT : (strcmp(direction, "left") == 0 ? D_LEFT : (strcmp(direction, "up") == 0 ? D_UP : D_DOWN))));
 +            tree_move(current->con, direction);
              cmd_output->needs_tree_render = true;
          }
      }
diff --combined src/handlers.c
index 5d0a6c624784c07dd25dbcf441ae11aa534a9504,f632d91cb1340e6a4918c69a82f7a6fe2c20576e..0b6858d9f7dcd2cc2b5aa716ce39b4e7bb39afe1
@@@ -310,16 -310,12 +310,12 @@@ static void handle_configure_request(xc
  
      DLOG("Configure request!\n");
  
-     Con *workspace = con_get_workspace(con),
-         *fullscreen = NULL;
-     /* There might not be a corresponding workspace for dock cons, therefore we
-      * have to be careful here. */
-     if (workspace) {
-         fullscreen = con_get_fullscreen_con(workspace, CF_OUTPUT);
-         if (!fullscreen)
-             fullscreen = con_get_fullscreen_con(workspace, CF_GLOBAL);
+     Con *workspace = con_get_workspace(con);
+     if (workspace && (strcmp(workspace->name, "__i3_scratch") == 0)) {
+         DLOG("This is a scratchpad container, ignoring ConfigureRequest\n");
+         goto out;
      }
+     Con *fullscreen = con_get_fullscreen_covering_ws(workspace);
  
      if (fullscreen != con && con_is_floating(con) && con_is_leaf(con)) {
          /* find the height for the decorations */
              bsr.height -= deco_height;
          }
          Con *floatingcon = con->parent;
-         if (strcmp(con_get_workspace(floatingcon)->name, "__i3_scratch") == 0) {
-             DLOG("This is a scratchpad container, ignoring ConfigureRequest\n");
-             return;
-         }
          Rect newrect = floatingcon->rect;
  
          if (event->value_mask & XCB_CONFIG_WINDOW_X) {
                  DLOG("Dock client will not be moved, we only support moving it to another output.\n");
              }
          }
-         fake_absolute_configure_notify(con);
-         return;
+         goto out;
      }
  
      if (event->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) {
          DLOG("window 0x%08x wants to be stacked %d\n", event->window, event->stack_mode);
  
          /* Emacs and IntelliJ Idea “request focus” by stacking their window
-              * above all others. */
+          * above all others. */
          if (event->stack_mode != XCB_STACK_MODE_ABOVE) {
              DLOG("stack_mode != XCB_STACK_MODE_ABOVE, ignoring ConfigureRequest\n");
              goto out;
              goto out;
          }
  
-         Con *ws = con_get_workspace(con);
-         if (ws == NULL) {
+         if (workspace == NULL) {
              DLOG("Window is not being managed, ignoring ConfigureRequest\n");
              goto out;
          }
  
-         if (strcmp(ws->name, "__i3_scratch") == 0) {
-             DLOG("This is a scratchpad container, ignoring ConfigureRequest\n");
-             goto out;
-         }
-         if (config.focus_on_window_activation == FOWA_FOCUS || (config.focus_on_window_activation == FOWA_SMART && workspace_is_visible(ws))) {
+         if (config.focus_on_window_activation == FOWA_FOCUS || (config.focus_on_window_activation == FOWA_SMART && workspace_is_visible(workspace))) {
              DLOG("Focusing con = %p\n", con);
-             workspace_show(ws);
+             workspace_show(workspace);
              con_activate(con);
              tree_render();
-         } else if (config.focus_on_window_activation == FOWA_URGENT || (config.focus_on_window_activation == FOWA_SMART && !workspace_is_visible(ws))) {
+         } else if (config.focus_on_window_activation == FOWA_URGENT || (config.focus_on_window_activation == FOWA_SMART && !workspace_is_visible(workspace))) {
              DLOG("Marking con = %p urgent\n", con);
              con_set_urgency(con, true);
              tree_render();
@@@ -1141,7 -1124,8 +1124,7 @@@ static bool handle_transient_for(void *
      }
  
      if (prop == NULL) {
 -        prop = xcb_get_property_reply(conn, xcb_get_property_unchecked(conn,
 -                                                                       false, window, XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 0, 32),
 +        prop = xcb_get_property_reply(conn, xcb_get_property_unchecked(conn, false, window, XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 0, 32),
                                        NULL);
          if (prop == NULL)
              return false;
@@@ -1164,7 -1148,8 +1147,7 @@@ static bool handle_clientleader_change(
          return false;
  
      if (prop == NULL) {
 -        prop = xcb_get_property_reply(conn, xcb_get_property_unchecked(conn,
 -                                                                       false, window, A_WM_CLIENT_LEADER, XCB_ATOM_WINDOW, 0, 32),
 +        prop = xcb_get_property_reply(conn, xcb_get_property_unchecked(conn, false, window, A_WM_CLIENT_LEADER, XCB_ATOM_WINDOW, 0, 32),
                                        NULL);
          if (prop == NULL)
              return false;
@@@ -1264,7 -1249,8 +1247,7 @@@ static bool handle_class_change(void *d
          return false;
  
      if (prop == NULL) {
 -        prop = xcb_get_property_reply(conn, xcb_get_property_unchecked(conn,
 -                                                                       false, window, XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 0, 32),
 +        prop = xcb_get_property_reply(conn, xcb_get_property_unchecked(conn, false, window, XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 0, 32),
                                        NULL);
  
          if (prop == NULL)
@@@ -1287,7 -1273,8 +1270,7 @@@ static bool handle_motif_hints_change(v
          return false;
  
      if (prop == NULL) {
 -        prop = xcb_get_property_reply(conn, xcb_get_property_unchecked(conn,
 -                                                                       false, window, A__MOTIF_WM_HINTS, XCB_GET_PROPERTY_TYPE_ANY, 0, 5 * sizeof(uint64_t)),
 +        prop = xcb_get_property_reply(conn, xcb_get_property_unchecked(conn, false, window, A__MOTIF_WM_HINTS, XCB_GET_PROPERTY_TYPE_ANY, 0, 5 * sizeof(uint64_t)),
                                        NULL);
  
          if (prop == NULL)
diff --combined src/render.c
index dafccbb1d9c7299f16050497723728abe667879c,d6306260721f0d025eda63ac988960fd032e27ec..d8bffc61f2b1a1232a16e10c248ac752db9d299e
@@@ -183,28 -183,26 +183,28 @@@ free_params
  }
  
  static int *precalculate_sizes(Con *con, render_params *p) {
 -    int *sizes = smalloc(p->children * sizeof(int));
 -    if ((con->layout == L_SPLITH || con->layout == L_SPLITV) && p->children > 0) {
 -        assert(!TAILQ_EMPTY(&con->nodes_head));
 +    if ((con->layout != L_SPLITH && con->layout != L_SPLITV) || p->children <= 0) {
 +        return NULL;
 +    }
  
 -        Con *child;
 -        int i = 0, assigned = 0;
 -        int total = con_orientation(con) == HORIZ ? p->rect.width : p->rect.height;
 -        TAILQ_FOREACH(child, &(con->nodes_head), nodes) {
 -            double percentage = child->percent > 0.0 ? child->percent : 1.0 / p->children;
 -            assigned += sizes[i++] = percentage * total;
 -        }
 -        assert(assigned == total ||
 -               (assigned > total && assigned - total <= p->children * 2) ||
 -               (assigned < total && total - assigned <= p->children * 2));
 -        int signal = assigned < total ? 1 : -1;
 -        while (assigned != total) {
 -            for (i = 0; i < p->children && assigned != total; ++i) {
 -                sizes[i] += signal;
 -                assigned += signal;
 -            }
 +    int *sizes = smalloc(p->children * sizeof(int));
 +    assert(!TAILQ_EMPTY(&con->nodes_head));
 +
 +    Con *child;
 +    int i = 0, assigned = 0;
 +    int total = con_orientation(con) == HORIZ ? p->rect.width : p->rect.height;
 +    TAILQ_FOREACH(child, &(con->nodes_head), nodes) {
 +        double percentage = child->percent > 0.0 ? child->percent : 1.0 / p->children;
 +        assigned += sizes[i++] = lround(percentage * total);
 +    }
 +    assert(assigned == total ||
 +           (assigned > total && assigned - total <= p->children * 2) ||
 +           (assigned < total && total - assigned <= p->children * 2));
 +    int signal = assigned < total ? 1 : -1;
 +    while (assigned != total) {
 +        for (i = 0; i < p->children && assigned != total; ++i) {
 +            sizes[i] += signal;
 +            assigned += signal;
          }
      }
  
@@@ -234,25 -232,22 +234,22 @@@ static void render_root(Con *con, Con *
              continue;
          }
          Con *workspace = TAILQ_FIRST(&(content->focus_head));
-         Con *fullscreen = con_get_fullscreen_con(workspace, CF_OUTPUT);
+         Con *fullscreen = con_get_fullscreen_covering_ws(workspace);
          Con *child;
          TAILQ_FOREACH(child, &(workspace->floating_head), floating_windows) {
-             /* Don’t render floating windows when there is a fullscreen window
-              * on that workspace. Necessary to make floating fullscreen work
-              * correctly (ticket #564). */
-             /* If there is no fullscreen->window, this cannot be a
-              * transient window, so we _know_ we need to skip it. This
-              * happens during restarts where the container already exists,
-              * but the window was not yet associated. */
-             if (fullscreen != NULL && fullscreen->window == NULL)
-                 continue;
-             if (fullscreen != NULL && fullscreen->window != NULL) {
+             if (fullscreen != NULL) {
+                 /* Don’t render floating windows when there is a fullscreen
+                  * window on that workspace. Necessary to make floating
+                  * fullscreen work correctly (ticket #564). Exception to the
+                  * above rule: smart popup_during_fullscreen handling (popups
+                  * belonging to the fullscreen app will be rendered). */
+                 if (config.popup_during_fullscreen != PDF_SMART) {
+                     continue;
+                 }
                  Con *floating_child = con_descend_focused(child);
                  Con *transient_con = floating_child;
                  bool is_transient_for = false;
-                 /* Exception to the above rule: smart
-                  * popup_during_fullscreen handling (popups belonging to
-                  * the fullscreen app will be rendered). */
                  while (transient_con != NULL &&
                         transient_con->window != NULL &&
                         transient_con->window->transient_for != XCB_NONE) {