Force correct separate title bar controls geometry.

This commit is contained in:
John Preston 2022-01-18 15:33:28 +03:00
parent 64fa3d83b5
commit e5c8a6ebc4
10 changed files with 104 additions and 3 deletions

View file

@ -41,6 +41,14 @@ QMargins BasicWindowHelper::frameMargins() {
return nativeFrameMargins();
}
int BasicWindowHelper::additionalContentPadding() const {
return 0;
}
rpl::producer<int> BasicWindowHelper::additionalContentPaddingValue() const {
return rpl::single(0);
}
void BasicWindowHelper::setTitle(const QString &title) {
_window->setWindowTitle(title);
}

View file

@ -29,6 +29,9 @@ public:
[[nodiscard]] virtual not_null<RpWidget*> body();
[[nodiscard]] virtual QMargins frameMargins();
[[nodiscard]] virtual int additionalContentPadding() const;
[[nodiscard]] virtual auto additionalContentPaddingValue() const
-> rpl::producer<int>;
virtual void setTitle(const QString &title);
virtual void setTitleStyle(const style::WindowTitle &st);
virtual void setNativeFrame(bool enabled);

View file

@ -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<void(bool maximized)> maximize)
: wrap(parent)
, controls(&wrap, st, std::move(maximize)) {
}
std::unique_ptr<SeparateTitleControls> SetupSeparateTitleControls(
not_null<RpWindow*> window,
const style::WindowTitle &st,
Fn<void(bool maximized)> maximize) {
auto result = std::make_unique<SeparateTitleControls>(
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

View file

@ -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<void(bool maximized)> maximize);
RpWidget wrap;
TitleControls controls;
};
[[nodiscard]] auto SetupSeparateTitleControls(
not_null<RpWindow*> window,
const style::WindowTitle &st,
Fn<void(bool maximized)> maximize = nullptr)
-> std::unique_ptr<SeparateTitleControls>;
} // namespace Platform
} // namespace Ui

View file

@ -48,7 +48,7 @@ struct TitleWidget::PaddingHelper {
}
RpWidget controlsParent;
int padding = 0;
rpl::variable<int> padding = 0;
};
TitleWidget::TitleWidget(not_null<RpWidget*> 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<int> 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;

View file

@ -42,6 +42,8 @@ public:
void refreshAdditionalPaddings(
HWND handle,
const WINDOWPLACEMENT &placement);
[[nodiscard]] int additionalPadding() const;
[[nodiscard]] rpl::producer<int> additionalPaddingValue() const;
void sysButtonOver(HitTestResult testResult);
void sysButtonDown(HitTestResult testResult, bool down);

View file

@ -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<int> 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);

View file

@ -24,6 +24,8 @@ public:
not_null<RpWidget*> body() override;
QMargins frameMargins() override;
int additionalContentPadding() const override;
rpl::producer<int> additionalContentPaddingValue() const override;
void setTitle(const QString &title) override;
void setTitleStyle(const style::WindowTitle &st) override;
void setNativeFrame(bool enabled) override;

View file

@ -32,6 +32,14 @@ QMargins RpWindow::frameMargins() const {
return _helper->frameMargins();
}
int RpWindow::additionalContentPadding() const {
return _helper->additionalContentPadding();
}
rpl::producer<int> RpWindow::additionalContentPaddingValue() const {
return _helper->additionalContentPaddingValue();
}
void RpWindow::setTitle(const QString &title) {
_helper->setTitle(title);
}

View file

@ -38,6 +38,14 @@ public:
[[nodiscard]] not_null<const RpWidget*> 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<int> additionalContentPaddingValue() const;
void setTitle(const QString &title);
void setTitleStyle(const style::WindowTitle &st);
void setNativeFrame(bool enabled);