diff --git a/ui/platform/ui_platform_window.cpp b/ui/platform/ui_platform_window.cpp index 9bb8c50..6042e0b 100644 --- a/ui/platform/ui_platform_window.cpp +++ b/ui/platform/ui_platform_window.cpp @@ -41,6 +41,14 @@ QMargins BasicWindowHelper::frameMargins() { return nativeFrameMargins(); } +int BasicWindowHelper::additionalContentPadding() const { + return 0; +} + +rpl::producer BasicWindowHelper::additionalContentPaddingValue() const { + return rpl::single(0); +} + void BasicWindowHelper::setTitle(const QString &title) { _window->setWindowTitle(title); } diff --git a/ui/platform/ui_platform_window.h b/ui/platform/ui_platform_window.h index fb84190..4eadb21 100644 --- a/ui/platform/ui_platform_window.h +++ b/ui/platform/ui_platform_window.h @@ -29,6 +29,9 @@ public: [[nodiscard]] virtual not_null body(); [[nodiscard]] virtual QMargins frameMargins(); + [[nodiscard]] virtual int additionalContentPadding() const; + [[nodiscard]] virtual auto additionalContentPaddingValue() const + -> rpl::producer; virtual void setTitle(const QString &title); virtual void setTitleStyle(const style::WindowTitle &st); virtual void setNativeFrame(bool enabled); diff --git a/ui/platform/ui_platform_window_title.cpp b/ui/platform/ui_platform_window_title.cpp index 9add5af..d46398c 100644 --- a/ui/platform/ui_platform_window_title.cpp +++ b/ui/platform/ui_platform_window_title.cpp @@ -10,6 +10,7 @@ #include "ui/widgets/buttons.h" #include "ui/widgets/shadow.h" #include "ui/ui_utility.h" +#include "ui/widgets/rp_window.h" #include "styles/style_widgets.h" #include "styles/palette.h" #include "base/algorithm.h" @@ -438,5 +439,36 @@ void DefaultTitleWidget::mouseDoubleClickEvent(QMouseEvent *e) { } } +SeparateTitleControls::SeparateTitleControls( + QWidget *parent, + const style::WindowTitle &st, + Fn maximize) +: wrap(parent) +, controls(&wrap, st, std::move(maximize)) { +} + +std::unique_ptr SetupSeparateTitleControls( + not_null window, + const style::WindowTitle &st, + Fn maximize) { + auto result = std::make_unique( + window->body(), + st, + std::move(maximize)); + + rpl::combine( + window->body()->widthValue(), + window->additionalContentPaddingValue() + ) | rpl::start_with_next([raw = result.get()](int width, int padding) { + raw->wrap.setGeometry( + padding, + 0, + width - 2 * padding, + raw->controls.geometry().height()); + }, result->wrap.lifetime()); + + return result; +} + } // namespace Platform } // namespace Ui diff --git a/ui/platform/ui_platform_window_title.h b/ui/platform/ui_platform_window_title.h index 31413f1..e5889b0 100644 --- a/ui/platform/ui_platform_window_title.h +++ b/ui/platform/ui_platform_window_title.h @@ -20,6 +20,7 @@ namespace Ui { class IconButton; class PlainShadow; +class RpWindow; namespace Platform { @@ -122,5 +123,21 @@ private: }; +struct SeparateTitleControls { + SeparateTitleControls( + QWidget *parent, + const style::WindowTitle &st, + Fn maximize); + + RpWidget wrap; + TitleControls controls; +}; + +[[nodiscard]] auto SetupSeparateTitleControls( + not_null window, + const style::WindowTitle &st, + Fn maximize = nullptr) +-> std::unique_ptr; + } // namespace Platform } // namespace Ui diff --git a/ui/platform/win/ui_window_title_win.cpp b/ui/platform/win/ui_window_title_win.cpp index f9f6566..1ae2dff 100644 --- a/ui/platform/win/ui_window_title_win.cpp +++ b/ui/platform/win/ui_window_title_win.cpp @@ -48,7 +48,7 @@ struct TitleWidget::PaddingHelper { } RpWidget controlsParent; - int padding = 0; + rpl::variable padding = 0; }; TitleWidget::TitleWidget(not_null parent) @@ -80,7 +80,7 @@ void TitleWidget::setStyle(const style::WindowTitle &st) { } void TitleWidget::refreshGeometryWithWidth(int width) { - const auto add = _paddingHelper ? _paddingHelper->padding : 0; + const auto add = additionalPadding(); setGeometry(0, 0, width, _controls.st()->height + add); if (_paddingHelper) { _paddingHelper->controlsParent.setGeometry( @@ -201,10 +201,18 @@ void TitleWidget::refreshAdditionalPaddings( setAdditionalPadding(padding); } +int TitleWidget::additionalPadding() const { + return _paddingHelper ? _paddingHelper->padding.current() : 0; +} + +rpl::producer TitleWidget::additionalPaddingValue() const { + return _paddingHelper ? _paddingHelper->padding.value() : rpl::single(0); +} + void TitleWidget::setAdditionalPadding(int padding) { Expects(_paddingHelper != nullptr); - if (_paddingHelper->padding == padding) { + if (_paddingHelper->padding.current() == padding) { return; } _paddingHelper->padding = padding; diff --git a/ui/platform/win/ui_window_title_win.h b/ui/platform/win/ui_window_title_win.h index 07f2639..88f4489 100644 --- a/ui/platform/win/ui_window_title_win.h +++ b/ui/platform/win/ui_window_title_win.h @@ -42,6 +42,8 @@ public: void refreshAdditionalPaddings( HWND handle, const WINDOWPLACEMENT &placement); + [[nodiscard]] int additionalPadding() const; + [[nodiscard]] rpl::producer additionalPaddingValue() const; void sysButtonOver(HitTestResult testResult); void sysButtonDown(HitTestResult testResult, bool down); diff --git a/ui/platform/win/ui_window_win.cpp b/ui/platform/win/ui_window_win.cpp index 7396cc4..01b89d3 100644 --- a/ui/platform/win/ui_window_win.cpp +++ b/ui/platform/win/ui_window_win.cpp @@ -179,6 +179,19 @@ QMargins WindowHelper::frameMargins() { : QMargins{ 0, _title->height(), 0, 0 }; } +int WindowHelper::additionalContentPadding() const { + return _title->isHidden() ? 0 : _title->additionalPadding(); +} + +rpl::producer WindowHelper::additionalContentPaddingValue() const { + return rpl::combine( + _title->shownValue(), + _title->additionalPaddingValue() + ) | rpl::map([](bool shown, int padding) { + return shown ? padding : 0; + }) | rpl::distinct_until_changed(); +} + void WindowHelper::setTitle(const QString &title) { _title->setText(title); window()->setWindowTitle(title); diff --git a/ui/platform/win/ui_window_win.h b/ui/platform/win/ui_window_win.h index e20f405..49b4bb7 100644 --- a/ui/platform/win/ui_window_win.h +++ b/ui/platform/win/ui_window_win.h @@ -24,6 +24,8 @@ public: not_null body() override; QMargins frameMargins() override; + int additionalContentPadding() const override; + rpl::producer additionalContentPaddingValue() const override; void setTitle(const QString &title) override; void setTitleStyle(const style::WindowTitle &st) override; void setNativeFrame(bool enabled) override; diff --git a/ui/widgets/rp_window.cpp b/ui/widgets/rp_window.cpp index 48f3a77..962845d 100644 --- a/ui/widgets/rp_window.cpp +++ b/ui/widgets/rp_window.cpp @@ -32,6 +32,14 @@ QMargins RpWindow::frameMargins() const { return _helper->frameMargins(); } +int RpWindow::additionalContentPadding() const { + return _helper->additionalContentPadding(); +} + +rpl::producer RpWindow::additionalContentPaddingValue() const { + return _helper->additionalContentPaddingValue(); +} + void RpWindow::setTitle(const QString &title) { _helper->setTitle(title); } diff --git a/ui/widgets/rp_window.h b/ui/widgets/rp_window.h index 4f4996e..ca0f8e8 100644 --- a/ui/widgets/rp_window.h +++ b/ui/widgets/rp_window.h @@ -38,6 +38,14 @@ public: [[nodiscard]] not_null body() const; [[nodiscard]] QMargins frameMargins() const; + // In Windows 11 the window rounding shadow takes about + // round(1px * system_scale) from the window geometry on each side. + // + // Top shift is made by the TitleWidget height, but the rest of the + // side shifts are left for the RpWindow client to consider. + [[nodiscard]] int additionalContentPadding() const; + [[nodiscard]] rpl::producer additionalContentPaddingValue() const; + void setTitle(const QString &title); void setTitleStyle(const style::WindowTitle &st); void setNativeFrame(bool enabled);