diff --git a/src/ui/dialog/dialog-multipaned.cpp b/src/ui/dialog/dialog-multipaned.cpp index 5483f469f4cc79ae60ff72362cea0a62c0bd2f78..c7e402615608d3a872915d6b186f3863c0b10863 100644 --- a/src/ui/dialog/dialog-multipaned.cpp +++ b/src/ui/dialog/dialog-multipaned.cpp @@ -767,7 +767,8 @@ void DialogMultipaned::on_size_allocate(Gtk::Allocation &allocation) std::vector sizes_minimums; // Difference between allocated space and minimum space. std::vector sizes_naturals; // Difference between allocated space and natural space. std::vector sizes_current; // The current sizes along main axis - int left = horizontal ? allocation.get_width() : allocation.get_height(); + /// Remaining space to allocate + int remaining = horizontal ? allocation.get_width() : allocation.get_height(); int index = 0; bool force_resize = false; // initially panels are not sized yet, so we will apply their natural sizes @@ -805,7 +806,18 @@ void DialogMultipaned::on_size_allocate(Gtk::Allocation &allocation) if (sizes_current.back() < sizes_minimums.back()) force_resize = true; } - std::vector sizes = sizes_current; // The new allocation sizes + std::vector sizes; ///< The new allocation sizes + if (horizontal) { + sizes = sizes_current; + } else { + // In vertical mode, enforce the minimum height to prevent a vertically + // docked dialog from getting squashed to 1px height; see + // https://gitlab.com/inkscape/inkscape/-/issues/4254 + sizes.reserve(sizes_current.size()); + for (size_t i = 0; i < sizes_current.size(); i++) { + sizes.push_back(std::max(sizes_current[i], sizes_minimums[i])); + } + } const int sum_current = std::accumulate(sizes_current.begin(), sizes_current.end(), 0); { @@ -814,13 +826,12 @@ void DialogMultipaned::on_size_allocate(Gtk::Allocation &allocation) const int sum_naturals = std::accumulate(sizes_naturals.begin(), sizes_naturals.end(), 0); // initial resize requested? - if (force_resize && sum_naturals <= left) { + if (force_resize && sum_naturals <= remaining) { sizes = sizes_naturals; - left -= sum_naturals; - } else if (sum_minimums <= left && left < sum_current) { + remaining -= sum_naturals; + } else if (sum_minimums <= remaining && remaining < sum_current) { // requested size exeeds available space; try shrinking it by starting from the last element - sizes = sizes_current; - auto excess = sum_current - left; + auto excess = sum_current - remaining; for (int i = static_cast(sizes.size() - 1); excess > 0 && i >= 0; --i) { auto extra = sizes_current[i] - sizes_minimums[i]; if (extra > 0) { @@ -839,32 +850,32 @@ void DialogMultipaned::on_size_allocate(Gtk::Allocation &allocation) if (excess > 0) { sizes = sizes_minimums; - left -= sum_minimums; + remaining -= sum_minimums; } else { - left = 0; + remaining = 0; } } else { - left = std::max(0, left - sum_current); + remaining = std::max(0, remaining - sum_current); } } if (canvas_index >= 0) { // give remaining space to canvas element - sizes[canvas_index] += left; + sizes[canvas_index] += remaining; } else { // or, if in a sub-dialogmultipaned, give it to the last panel for (int i = static_cast(children.size()) - 1; i >= 0; --i) { if (expandables[i]) { - sizes[i] += left; + sizes[i] += remaining; break; } } } // Check if we actually need to change the sizes on the main axis - left = horizontal ? allocation.get_width() : allocation.get_height(); - if (left == sum_current) { + remaining = horizontal ? allocation.get_width() : allocation.get_height(); + if (remaining == sum_current) { bool valid = true; for (size_t i = 0; i < children.size(); ++i) { valid = sizes_minimums[i] <= sizes_current[i] && // is it over the minimums?