|
@@ -467,6 +467,36 @@ Messages::WindowServer::GetWindowRectResponse ConnectionFromClient::get_window_r
|
|
|
return it->value->rect();
|
|
|
}
|
|
|
|
|
|
+static Gfx::IntSize calculate_minimum_size_for_window(Window const& window)
|
|
|
+{
|
|
|
+ // NOTE: Windows with a title bar have a minimum size enforced by the system,
|
|
|
+ // because we want to always keep their title buttons accessible.
|
|
|
+ if (window.type() == WindowType::Normal || window.type() == WindowType::ToolWindow) {
|
|
|
+ auto palette = WindowManager::the().palette();
|
|
|
+
|
|
|
+ int required_width = 0;
|
|
|
+ // Padding on left and right of window title content.
|
|
|
+ // FIXME: This seems like it should be defined in the theme.
|
|
|
+ required_width += 2 + 2;
|
|
|
+ // App icon
|
|
|
+ required_width += 16;
|
|
|
+ // Padding between icon and buttons
|
|
|
+ required_width += 2;
|
|
|
+ // Close button
|
|
|
+ required_width += palette.window_title_button_width();
|
|
|
+ // Maximize button
|
|
|
+ if (window.is_resizable())
|
|
|
+ required_width += palette.window_title_button_width();
|
|
|
+ // Minimize button
|
|
|
+ if (window.is_minimizable())
|
|
|
+ required_width += palette.window_title_button_width();
|
|
|
+
|
|
|
+ return { required_width, 0 };
|
|
|
+ }
|
|
|
+
|
|
|
+ return { 0, 0 };
|
|
|
+}
|
|
|
+
|
|
|
void ConnectionFromClient::set_window_minimum_size(i32 window_id, Gfx::IntSize const& size)
|
|
|
{
|
|
|
auto it = m_windows.find(window_id);
|
|
@@ -480,7 +510,9 @@ void ConnectionFromClient::set_window_minimum_size(i32 window_id, Gfx::IntSize c
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- window.set_minimum_size(size);
|
|
|
+ auto system_window_minimum_size = calculate_minimum_size_for_window(window);
|
|
|
+ window.set_minimum_size({ max(size.width(), system_window_minimum_size.width()),
|
|
|
+ max(size.height(), system_window_minimum_size.height()) });
|
|
|
|
|
|
if (window.width() < window.minimum_size().width() || window.height() < window.minimum_size().height()) {
|
|
|
// New minimum size is larger than the current window size, resize accordingly.
|
|
@@ -569,7 +601,9 @@ void ConnectionFromClient::create_window(i32 window_id, Gfx::IntRect const& rect
|
|
|
new_rect = { WindowManager::the().get_recommended_window_position({ 100, 100 }), rect.size() };
|
|
|
window->set_default_positioned(true);
|
|
|
}
|
|
|
- window->set_minimum_size(minimum_size);
|
|
|
+ auto system_window_minimum_size = calculate_minimum_size_for_window(window);
|
|
|
+ window->set_minimum_size({ max(minimum_size.width(), system_window_minimum_size.width()),
|
|
|
+ max(minimum_size.height(), system_window_minimum_size.height()) });
|
|
|
bool did_size_clamp = window->apply_minimum_size(new_rect);
|
|
|
window->set_rect(new_rect);
|
|
|
window->nudge_into_desktop(nullptr);
|
|
@@ -1284,4 +1318,29 @@ void ConnectionFromClient::remove_window_stealing(i32 window_id)
|
|
|
window->remove_all_stealing();
|
|
|
}
|
|
|
|
|
|
+void ConnectionFromClient::notify_about_theme_change()
|
|
|
+{
|
|
|
+ // Recalculate minimum size for each window, using the new theme metrics.
|
|
|
+ // FIXME: We only ever increase the minimum size, which means that if you go from a theme with large buttons
|
|
|
+ // (eg Basalt) to one with smaller buttons (eg Default) then the minimum size will remain large. This
|
|
|
+ // only happens with pre-existing windows, and it's unlikely that you will ever have windows that are
|
|
|
+ // so small, so it's probably fine, but it is technically a bug. :^)
|
|
|
+ for_each_window([](auto& window) -> IterationDecision {
|
|
|
+ auto system_window_minimum_size = calculate_minimum_size_for_window(window);
|
|
|
+
|
|
|
+ auto old_minimum_size = window.minimum_size();
|
|
|
+ auto new_rect = window.rect();
|
|
|
+
|
|
|
+ window.set_minimum_size({ max(old_minimum_size.width(), system_window_minimum_size.width()),
|
|
|
+ max(old_minimum_size.height(), system_window_minimum_size.height()) });
|
|
|
+ if (window.apply_minimum_size(new_rect)) {
|
|
|
+ window.set_rect(new_rect);
|
|
|
+ window.refresh_client_size();
|
|
|
+ }
|
|
|
+
|
|
|
+ return IterationDecision::Continue;
|
|
|
+ });
|
|
|
+ async_update_system_theme(Gfx::current_system_theme_buffer());
|
|
|
+}
|
|
|
+
|
|
|
}
|