From 52ac632bc4b0c7c9e80d012e6aa6ba154949e0ef Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 23 Mar 2021 16:32:21 +0400 Subject: [PATCH 1/4] Allow destroying Ui::Window on close. --- ui/integration.cpp | 4 ++++ ui/integration.h | 2 ++ ui/platform/ui_platform_window_title.cpp | 15 ++++++++++++--- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/ui/integration.cpp b/ui/integration.cpp index ae49b3e..f8df624 100644 --- a/ui/integration.cpp +++ b/ui/integration.cpp @@ -79,6 +79,10 @@ const Emoji::One *Integration::defaultEmojiVariant(const Emoji::One *emoji) { return emoji; } +QWidget *Integration::modalWindowParent() { + return nullptr; +} + rpl::producer<> Integration::forcePopupMenuHideRequests() { return rpl::never(); } diff --git a/ui/integration.h b/ui/integration.h index 0ae8343..e3c90db 100644 --- a/ui/integration.h +++ b/ui/integration.h @@ -56,6 +56,8 @@ public: [[nodiscard]] virtual const Emoji::One *defaultEmojiVariant( const Emoji::One *emoji); + [[nodiscard]] virtual QWidget *modalWindowParent(); + [[nodiscard]] virtual rpl::producer<> forcePopupMenuHideRequests(); [[nodiscard]] virtual QString phraseContextCopyText(); diff --git a/ui/platform/ui_platform_window_title.cpp b/ui/platform/ui_platform_window_title.cpp index 1a5b406..7da20ec 100644 --- a/ui/platform/ui_platform_window_title.cpp +++ b/ui/platform/ui_platform_window_title.cpp @@ -90,12 +90,16 @@ not_null TitleControls::window() const { void TitleControls::init(Fn maximize) { _minimize->setClickedCallback([=] { + const auto weak = MakeWeak(_minimize.data()); window()->setWindowState( window()->windowState() | Qt::WindowMinimized); - _minimize->clearState(); + if (weak) { + _minimize->clearState(); + } }); _minimize->setPointerCursor(false); _maximizeRestore->setClickedCallback([=] { + const auto weak = MakeWeak(_maximizeRestore.data()); if (maximize) { maximize(!_maximizedState); } else { @@ -103,12 +107,17 @@ void TitleControls::init(Fn maximize) { ? Qt::WindowNoState : Qt::WindowMaximized); } - _maximizeRestore->clearState(); + if (weak) { + _maximizeRestore->clearState(); + } }); _maximizeRestore->setPointerCursor(false); _close->setClickedCallback([=] { + const auto weak = MakeWeak(_close.data()); window()->close(); - _close->clearState(); + if (weak) { + _close->clearState(); + } }); _close->setPointerCursor(false); From f288c5649c1d517ab0510d9275b735a4398b6db4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 26 Mar 2021 21:05:02 +0400 Subject: [PATCH 2/4] Add MaskedInputField::showErrorNoFocus. --- ui/widgets/input_fields.cpp | 14 +++++++++++++- ui/widgets/input_fields.h | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/ui/widgets/input_fields.cpp b/ui/widgets/input_fields.cpp index bb51148..011bdf7 100644 --- a/ui/widgets/input_fields.cpp +++ b/ui/widgets/input_fields.cpp @@ -3569,6 +3569,10 @@ void InputField::showErrorNoFocus() { setErrorShown(true); } +void InputField::hideError() { + setErrorShown(false); +} + void InputField::setErrorShown(bool error) { if (_error != error) { _error = error; @@ -3886,12 +3890,20 @@ void MaskedInputField::inputMethodEvent(QInputMethodEvent *e) { } void MaskedInputField::showError() { - setErrorShown(true); + showErrorNoFocus(); if (!hasFocus()) { setFocus(); } } +void MaskedInputField::showErrorNoFocus() { + setErrorShown(true); +} + +void MaskedInputField::hideError() { + setErrorShown(false); +} + void MaskedInputField::setErrorShown(bool error) { if (_error != error) { _error = error; diff --git a/ui/widgets/input_fields.h b/ui/widgets/input_fields.h index daee290..6d18aa7 100644 --- a/ui/widgets/input_fields.h +++ b/ui/widgets/input_fields.h @@ -189,6 +189,7 @@ public: void showError(); void showErrorNoFocus(); + void hideError(); void setMaxLength(int maxLength); void setMinHeight(int minHeight); @@ -557,6 +558,8 @@ public: const QString &val = QString()); void showError(); + void showErrorNoFocus(); + void hideError(); QRect getTextRect() const; From d1dda0b2ac6c90ef906696be346360c3b547594c Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 2 Apr 2021 14:14:47 +0400 Subject: [PATCH 3/4] Add a new color and style::complex_color. --- ui/colors.palette | 2 + ui/style/style_core_color.cpp | 16 ++++++-- ui/style/style_core_color.h | 73 ++++++++++++++++++++++++++++++++++- ui/style/style_core_types.h | 2 + 4 files changed, 89 insertions(+), 4 deletions(-) diff --git a/ui/colors.palette b/ui/colors.palette index 00b6fb2..1fe974d 100644 --- a/ui/colors.palette +++ b/ui/colors.palette @@ -140,6 +140,8 @@ boxTitleCloseFgOver: cancelIconFgOver; // settings close icon and box search can //boxSearchCancelIconFg: cancelIconFg; // search cancel X button icon (like in contacts box) (not implemented yet) //boxSearchCancelIconFgOver: cancelIconFgOver; // search cancel X button icon with mouse over (not implemented yet) +paymentsTipActive: #01ad0f; // tip button text in payments checkout form + membersAboutLimitFg: windowSubTextFgOver; // text in channel members box about the limit (max 200 last members are shown) contactsBg: windowBg; // contacts (and some other) box row background diff --git a/ui/style/style_core_color.cpp b/ui/style/style_core_color.cpp index 4ab3533..8e3a29b 100644 --- a/ui/style/style_core_color.cpp +++ b/ui/style/style_core_color.cpp @@ -12,11 +12,14 @@ namespace style { namespace internal { Color::Proxy Color::operator[](const style::palette &paletteOverride) const { - auto index = main_palette::indexOfColor(*this); - return Proxy((index >= 0) ? paletteOverride.colorAtIndex(index) : (*this)); + const auto index = main_palette::indexOfColor(*this); + return { (index >= 0) ? paletteOverride.colorAtIndex(index) : (*this) }; } -ColorData::ColorData(uchar r, uchar g, uchar b, uchar a) : c(int(r), int(g), int(b), int(a)), p(c), b(c) { +ColorData::ColorData(uchar r, uchar g, uchar b, uchar a) +: c(int(r), int(g), int(b), int(a)) +, p(c) +, b(c) { } void ColorData::set(uchar r, uchar g, uchar b, uchar a) { @@ -25,5 +28,12 @@ void ColorData::set(uchar r, uchar g, uchar b, uchar a) { this->b = QBrush(c); } +void ComplexColor::subscribeToPaletteChanges() { + style::PaletteChanged( + ) | rpl::start_with_next([=] { + _owned.update(_generator()); + }, _lifetime); +} + } // namespace internal } // namespace style diff --git a/ui/style/style_core_color.h b/ui/style/style_core_color.h index d6b0e6f..8dfca90 100644 --- a/ui/style/style_core_color.h +++ b/ui/style/style_core_color.h @@ -10,6 +10,8 @@ #include #include +#include + namespace style { class palette; @@ -17,13 +19,15 @@ class palette; namespace internal { class Color; +class OwnedColor; + class ColorData { public: QColor c; QPen p; QBrush b; - QColor transparent() const { + [[nodiscard]] QColor transparent() const { return QColor(c.red(), c.green(), c.blue(), 0); } @@ -35,6 +39,7 @@ private: void set(uchar r, uchar g, uchar b, uchar a); friend class Color; + friend class OwnedColor; friend class style::palette; }; @@ -73,7 +78,9 @@ public: Proxy operator[](const style::palette &paletteOverride) const; private: + friend class OwnedColor; friend class style::palette; + Color(ColorData *data) : _data(data) { } @@ -81,6 +88,70 @@ private: }; +class OwnedColor final { +public: + explicit OwnedColor(const QColor &color) + : _data(color.red(), color.green(), color.blue(), color.alpha()) + , _color(&_data) { + } + + OwnedColor(const OwnedColor &other) + : _data(other._data) + , _color(&_data) { + } + + OwnedColor &operator=(const OwnedColor &other) { + _data = other._data; + return *this; + } + + void update(const QColor &color) { + _data.set(color.red(), color.green(), color.blue(), color.alpha()); + } + + [[nodiscard]] const Color &color() const { + return _color; + } + +private: + ColorData _data; + Color _color; + +}; + +class ComplexColor final { +public: + explicit ComplexColor(Fn generator) + : _owned(generator()) + , _generator(std::move(generator)) { + subscribeToPaletteChanges(); + } + + ComplexColor(const ComplexColor &other) + : _owned(other._owned) + , _generator(other._generator) { + subscribeToPaletteChanges(); + } + + ComplexColor &operator=(const ComplexColor &other) { + _owned = other._owned; + _generator = other._generator; + return *this; + } + + [[nodiscard]] const Color &color() const { + return _owned.color(); + } + +private: + void subscribeToPaletteChanges(); + + OwnedColor _owned; + Fn _generator; + rpl::lifetime _lifetime; + +}; + class Color::Proxy { public: Proxy(Color color) : _color(color) { diff --git a/ui/style/style_core_types.h b/ui/style/style_core_types.h index cc04a55..9cb4baa 100644 --- a/ui/style/style_core_types.h +++ b/ui/style/style_core_types.h @@ -28,6 +28,8 @@ using align = Qt::Alignment; using margins = QMargins; using font = internal::Font; using color = internal::Color; +using owned_color = internal::OwnedColor; +using complex_color = internal::ComplexColor; using icon = internal::Icon; static constexpr cursor cur_default = Qt::ArrowCursor; From 99089134e34c19e4c6fdb25569ade0d6f081bdb1 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Mon, 5 Apr 2021 10:23:42 +0400 Subject: [PATCH 4/4] Add a method to clear transient parent --- ui/platform/linux/ui_utility_linux.cpp | 11 +++++++++++ ui/platform/mac/ui_utility_mac.h | 3 +++ ui/platform/ui_platform_utility.h | 1 + ui/platform/win/ui_utility_win.h | 3 +++ 4 files changed, 18 insertions(+) diff --git a/ui/platform/linux/ui_utility_linux.cpp b/ui/platform/linux/ui_utility_linux.cpp index bfcc482..b61e47b 100644 --- a/ui/platform/linux/ui_utility_linux.cpp +++ b/ui/platform/linux/ui_utility_linux.cpp @@ -184,6 +184,17 @@ bool TranslucentWindowsSupported(QPoint globalPosition) { void IgnoreAllActivation(not_null widget) { } +void ClearTransientParent(not_null widget) { +#ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION + if (::Platform::IsX11()) { + xcb_delete_property( + base::Platform::XCB::GetConnectionFromQt(), + widget->windowHandle()->winId(), + XCB_ATOM_WM_TRANSIENT_FOR); + } +#endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION +} + bool WindowExtentsSupported() { #ifdef DESKTOP_APP_QT_PATCHED if (::Platform::IsWayland()) { diff --git a/ui/platform/mac/ui_utility_mac.h b/ui/platform/mac/ui_utility_mac.h index 97f3c11..070f3ee 100644 --- a/ui/platform/mac/ui_utility_mac.h +++ b/ui/platform/mac/ui_utility_mac.h @@ -20,6 +20,9 @@ inline bool TranslucentWindowsSupported(QPoint globalPosition) { inline void UpdateOverlayed(not_null widget) { } +inline void ClearTransientParent(not_null widget) { +} + inline constexpr bool UseMainQueueGeneric() { return ::Platform::IsMacStoreBuild(); } diff --git a/ui/platform/ui_platform_utility.h b/ui/platform/ui_platform_utility.h index 40dcdff..3360418 100644 --- a/ui/platform/ui_platform_utility.h +++ b/ui/platform/ui_platform_utility.h @@ -28,6 +28,7 @@ void UpdateOverlayed(not_null widget); void ShowOverAll(not_null widget, bool canFocus = true); void BringToBack(not_null widget); void IgnoreAllActivation(not_null widget); +void ClearTransientParent(not_null widget); [[nodiscard]] constexpr bool UseMainQueueGeneric(); void DrainMainQueue(); // Needed only if UseMainQueueGeneric() is false. diff --git a/ui/platform/win/ui_utility_win.h b/ui/platform/win/ui_utility_win.h index d836b49..e517414 100644 --- a/ui/platform/win/ui_utility_win.h +++ b/ui/platform/win/ui_utility_win.h @@ -38,6 +38,9 @@ inline void ShowOverAll(not_null widget, bool canFocus) { inline void BringToBack(not_null widget) { } +inline void ClearTransientParent(not_null widget) { +} + inline constexpr bool UseMainQueueGeneric() { return true; }