Add option for a native window frame.

Fixes #2958.
This commit is contained in:
John Preston 2020-07-07 17:54:39 +04:00
parent d1050e6041
commit f10b2194e6
19 changed files with 314 additions and 111 deletions

View File

@ -338,6 +338,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_update_fail" = "Update check failed :(";
"lng_settings_workmode_tray" = "Show tray icon";
"lng_settings_workmode_window" = "Show taskbar icon";
"lng_settings_native_frame" = "Use system window frame";
"lng_settings_auto_start" = "Launch Telegram when system starts";
"lng_settings_start_min" = "Launch minimized";
"lng_settings_add_sendto" = "Place Telegram in \"Send to\" menu";

View File

@ -105,7 +105,8 @@ QByteArray Settings::serialize() const {
1000000))
<< qint32(_thirdColumnWidth.current())
<< qint32(_thirdSectionExtendedBy)
<< qint32(_notifyFromAll ? 1 : 0);
<< qint32(_notifyFromAll ? 1 : 0)
<< qint32(_nativeWindowFrame.current() ? 1 : 0);
}
return result;
}
@ -169,6 +170,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
qint32 thirdColumnWidth = _thirdColumnWidth.current();
qint32 thirdSectionExtendedBy = _thirdSectionExtendedBy;
qint32 notifyFromAll = _notifyFromAll ? 1 : 0;
qint32 nativeWindowFrame = _nativeWindowFrame.current() ? 1 : 0;
stream >> themesAccentColors;
if (!stream.atEnd()) {
@ -243,6 +245,9 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
>> notifyFromAll;
dialogsWidthRatio = snap(dialogsWidthRatioInt / 1000000., 0., 1.);
}
if (!stream.atEnd()) {
stream >> nativeWindowFrame;
}
if (stream.status() != QDataStream::Ok) {
LOG(("App Error: "
"Bad data for Core::Settings::constructFromSerialized()"));
@ -335,6 +340,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
_tabbedSelectorSectionEnabled = false;
}
_notifyFromAll = (notifyFromAll == 1);
_nativeWindowFrame = (nativeWindowFrame == 1);
}
bool Settings::chatWide() const {

View File

@ -407,6 +407,15 @@ public:
[[nodiscard]] bool notifyFromAll() const {
return _notifyFromAll;
}
void setNativeWindowFrame(bool value) {
_nativeWindowFrame = value;
}
[[nodiscard]] bool nativeWindowFrame() const {
return _nativeWindowFrame.current();
}
[[nodiscard]] rpl::producer<bool> nativeWindowFrameChanges() const {
return _nativeWindowFrame.changes();
}
[[nodiscard]] static bool ThirdColumnByDefault();
[[nodiscard]] float64 DefaultDialogsWidthRatio();
@ -474,6 +483,7 @@ private:
rpl::variable<float64> _dialogsWidthRatio; // per-window
rpl::variable<int> _thirdColumnWidth = kDefaultThirdColumnWidth; // p-w
bool _notifyFromAll = true;
rpl::variable<bool> _nativeWindowFrame = false;
bool _tabbedReplacedWithInfo = false; // per-window
rpl::event_stream<bool> _tabbedReplacedWithInfoValue; // per-window

View File

@ -2177,13 +2177,19 @@ void MainWidget::updateControlsGeometry() {
auto mainSectionWidth = width() - dialogsWidth - thirdSectionWidth;
_dialogs->setGeometryWithTopMoved({ 0, 0, dialogsWidth, height() }, _contentScrollAddToY);
_sideShadow->setGeometryToLeft(dialogsWidth, 0, st::lineWidth, height());
const auto shadowTop = _controller->window().verticalShadowTop();
const auto shadowHeight = height() - shadowTop;
_sideShadow->setGeometryToLeft(
dialogsWidth,
shadowTop,
st::lineWidth,
shadowHeight);
if (_thirdShadow) {
_thirdShadow->setGeometryToLeft(
width() - thirdSectionWidth - st::lineWidth,
0,
shadowTop,
st::lineWidth,
height());
shadowHeight);
}
if (_callTopBar) {
_callTopBar->resizeToWidth(mainSectionWidth);

View File

@ -63,8 +63,6 @@ public:
void checkHistoryActivation();
void fixOrder();
void sendPaths();
QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) override;
@ -79,6 +77,7 @@ public:
void showMainMenu();
void updateTrayMenu(bool force = false) override;
void fixOrder() override;
void showSpecialLayer(
object_ptr<Ui::LayerWidget> layer,

View File

@ -22,14 +22,22 @@ void DefaultPreviewWindowFramePaint(QImage &preview, const style::palette &palet
namespace Platform {
inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
inline bool AllowNativeWindowFrameToggle() {
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
if (!DesktopEnvironment::IsUnity()) {
return object_ptr<Window::TitleWidgetQt>(parent);
}
return !DesktopEnvironment::IsUnity();
#else // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
return false;
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
}
return { nullptr };
inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
return AllowNativeWindowFrameToggle()
? object_ptr<Window::TitleWidgetQt>(parent)
: object_ptr<Window::TitleWidgetQt>{ nullptr };
}
inline bool NativeTitleRequiresShadow() {
return false;
}
inline int PreviewTitleHeight() {

View File

@ -32,8 +32,16 @@ private:
};
inline bool AllowNativeWindowFrameToggle() {
return false;
}
object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent);
inline bool NativeTitleRequiresShadow() {
return false;
}
int PreviewTitleHeight();
void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth);

View File

@ -14,7 +14,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Platform {
bool AllowNativeWindowFrameToggle();
object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent);
bool NativeTitleRequiresShadow();
int PreviewTitleHeight();
void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth);
@ -33,12 +35,22 @@ void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRe
namespace Platform {
inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
inline bool AllowNativeWindowFrameToggle() {
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
return object_ptr<Window::TitleWidgetQt>(parent);
return true;
#else // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
return false;
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
}
return { nullptr };
inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
return AllowNativeWindowFrameToggle()
? object_ptr<Window::TitleWidgetQt>(parent)
: object_ptr<Window::TitleWidgetQt>{ nullptr };
}
inline bool NativeTitleRequiresShadow() {
return false;
}
inline int PreviewTitleHeight() {

View File

@ -112,6 +112,12 @@ MainWindow::MainWindow(not_null<Window::Controller*> controller)
_shadow->setColor(st::windowShadowFg->c);
}
});
Core::App().settings().nativeWindowFrameChanges(
) | rpl::start_with_next([=] {
initShadows();
validateWindowTheme();
fixMaximizedWindow();
}, lifetime());
}
void MainWindow::TaskbarCreated() {
@ -231,6 +237,10 @@ void MainWindow::workmodeUpdated(DBIWorkMode mode) {
}
}
void MainWindow::updateWindowIcon() {
updateIconCounters();
}
void MainWindow::unreadCounterChangedHook() {
setWindowTitle(titleText());
updateIconCounters();
@ -294,18 +304,24 @@ void MainWindow::initHook() {
}
psInitSysMenu();
_shadow.emplace(this, st::windowShadowFg->c);
}
void MainWindow::initShadows() {
psUpdateMargins();
shadowsUpdate(Ui::Platform::WindowShadow::Change::Hidden);
if (Core::App().settings().nativeWindowFrame()) {
_shadow.reset();
} else {
_shadow.emplace(this, st::windowShadowFg->c);
}
updateCustomMargins();
firstShadowsUpdate();
}
void MainWindow::firstShadowsUpdate() {
if (!(windowState() & Qt::WindowMinimized) && !isHidden()) {
using Change = Ui::Platform::WindowShadow::Change;
using Change = Ui::Platform::WindowShadow::Change;
if ((windowState() & (Qt::WindowMinimized | Qt::WindowMaximized))
|| isHidden()) {
shadowsUpdate(Change::Hidden);
} else {
shadowsUpdate(Change::Moved | Change::Resized | Change::Shown);
}
}
@ -363,19 +379,40 @@ void MainWindow::updateSystemMenu(Qt::WindowState state) {
}
}
void MainWindow::psUpdateMargins() {
if (!ps_hWnd || _inUpdateMargins) return;
void MainWindow::updateCustomMargins() {
if (!ps_hWnd || _inUpdateMargins) {
return;
}
_inUpdateMargins = true;
RECT r, a;
const auto margins = computeCustomMargins();
if (const auto native = QGuiApplication::platformNativeInterface()) {
native->setWindowProperty(
windowHandle()->handle(),
qsl("WindowsCustomMargins"),
QVariant::fromValue<QMargins>(margins));
}
if (!_themeInited) {
_themeInited = true;
validateWindowTheme();
}
_inUpdateMargins = false;
}
QMargins MainWindow::computeCustomMargins() {
if (Core::App().settings().nativeWindowFrame()) {
_deltaLeft = _deltaTop = _deltaRight = _deltaBottom = 0;
return QMargins();
}
auto r = RECT();
GetClientRect(ps_hWnd, &r);
a = r;
LONG style = GetWindowLongPtr(ps_hWnd, GWL_STYLE), styleEx = GetWindowLongPtr(ps_hWnd, GWL_EXSTYLE);
auto a = r;
const auto style = GetWindowLongPtr(ps_hWnd, GWL_STYLE);
const auto styleEx = GetWindowLongPtr(ps_hWnd, GWL_EXSTYLE);
AdjustWindowRectEx(&a, style, false, styleEx);
QMargins margins = QMargins(a.left - r.left, a.top - r.top, r.right - a.right, r.bottom - a.bottom);
auto margins = QMargins(a.left - r.left, a.top - r.top, r.right - a.right, r.bottom - a.bottom);
if (style & WS_MAXIMIZE) {
RECT w, m;
GetWindowRect(ps_hWnd, &w);
@ -404,23 +441,39 @@ void MainWindow::psUpdateMargins() {
SetWindowPos(ps_hWnd, 0, 0, 0, w.right - w.left - _deltaLeft - _deltaRight, w.bottom - w.top - _deltaBottom - _deltaTop, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREPOSITION);
_deltaLeft = _deltaTop = _deltaRight = _deltaBottom = 0;
}
return margins;
}
if (const auto native = QGuiApplication::platformNativeInterface()) {
native->setWindowProperty(
windowHandle()->handle(),
qsl("WindowsCustomMargins"),
QVariant::fromValue<QMargins>(margins));
void MainWindow::validateWindowTheme() {
if (IsWindows8OrGreater()) {
return;
} else if (Dlls::SetWindowTheme != nullptr) {
if (Core::App().settings().nativeWindowFrame()) {
Dlls::SetWindowTheme(ps_hWnd, nullptr, nullptr);
} else {
Dlls::SetWindowTheme(ps_hWnd, L" ", L" ");
}
QApplication::setStyle(QStyleFactory::create(qsl("Windows")));
}
if (!_themeInited) {
_themeInited = true;
if (!IsWindows8OrGreater()) {
if (Dlls::SetWindowTheme != nullptr) {
Dlls::SetWindowTheme(ps_hWnd, L" ", L" ");
QApplication::setStyle(QStyleFactory::create(qsl("Windows")));
}
}
void MainWindow::fixMaximizedWindow() {
auto r = RECT();
GetClientRect(ps_hWnd, &r);
const auto style = GetWindowLongPtr(ps_hWnd, GWL_STYLE);
const auto styleEx = GetWindowLongPtr(ps_hWnd, GWL_EXSTYLE);
AdjustWindowRectEx(&r, style, false, styleEx);
if (style & WS_MAXIMIZE) {
auto w = RECT();
GetWindowRect(ps_hWnd, &w);
if (const auto hMonitor = MonitorFromRect(&w, MONITOR_DEFAULTTONEAREST)) {
MONITORINFO mi;
mi.cbSize = sizeof(mi);
GetMonitorInfo(hMonitor, &mi);
const auto m = mi.rcWork;
SetWindowPos(ps_hWnd, 0, 0, 0, m.right - m.left - _deltaLeft - _deltaRight, m.bottom - m.top - _deltaTop - _deltaBottom, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREPOSITION);
}
}
_inUpdateMargins = false;
}
HWND MainWindow::psHwnd() const {

View File

@ -31,7 +31,9 @@ public:
void psInitSysMenu();
void updateSystemMenu(Qt::WindowState state);
void psUpdateMargins();
void updateCustomMargins();
void updateWindowIcon() override;
void psRefreshTaskbarIcon();
@ -89,8 +91,10 @@ protected:
private:
void updateIconCounters();
QMargins computeCustomMargins();
void validateWindowTheme();
void psDestroyIcons();
void fixMaximizedWindow();
static UINT _taskbarCreatedMsgId;

View File

@ -59,10 +59,18 @@ private:
};
inline bool AllowNativeWindowFrameToggle() {
return true;
}
inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
return object_ptr<TitleWidget>(parent);
}
inline bool NativeTitleRequiresShadow() {
return true;
}
inline int PreviewTitleHeight() {
return Window::Theme::DefaultPreviewTitleHeight();
}

View File

@ -78,6 +78,79 @@ bool EventFilter::nativeEventFilter(
});
}
bool EventFilter::customWindowFrameEvent(
HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam,
LRESULT *result) {
switch (msg) {
case WM_NCPAINT: {
if (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8) return false;
if (result) *result = 0;
} return true;
case WM_NCCALCSIZE: {
WINDOWPLACEMENT wp;
wp.length = sizeof(WINDOWPLACEMENT);
if (GetWindowPlacement(hWnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED) {
LPNCCALCSIZE_PARAMS params = (LPNCCALCSIZE_PARAMS)lParam;
LPRECT r = (wParam == TRUE) ? &params->rgrc[0] : (LPRECT)lParam;
HMONITOR hMonitor = MonitorFromPoint({ (r->left + r->right) / 2, (r->top + r->bottom) / 2 }, MONITOR_DEFAULTTONEAREST);
if (hMonitor) {
MONITORINFO mi;
mi.cbSize = sizeof(mi);
if (GetMonitorInfo(hMonitor, &mi)) {
*r = mi.rcWork;
}
}
}
if (result) *result = 0;
return true;
}
case WM_NCACTIVATE: {
if (IsCompositionEnabled()) {
const auto res = DefWindowProc(hWnd, msg, wParam, -1);
if (result) *result = res;
} else {
// Thanks https://github.com/melak47/BorderlessWindow
if (result) *result = 1;
}
} return true;
case WM_NCHITTEST: {
if (!result) return false;
POINTS p = MAKEPOINTS(lParam);
RECT r;
GetWindowRect(hWnd, &r);
auto res = _window->hitTest(QPoint(p.x - r.left + _window->deltaLeft(), p.y - r.top + _window->deltaTop()));
switch (res) {
case Window::HitTestResult::Client:
case Window::HitTestResult::SysButton: *result = HTCLIENT; break;
case Window::HitTestResult::Caption: *result = HTCAPTION; break;
case Window::HitTestResult::Top: *result = HTTOP; break;
case Window::HitTestResult::TopRight: *result = HTTOPRIGHT; break;
case Window::HitTestResult::Right: *result = HTRIGHT; break;
case Window::HitTestResult::BottomRight: *result = HTBOTTOMRIGHT; break;
case Window::HitTestResult::Bottom: *result = HTBOTTOM; break;
case Window::HitTestResult::BottomLeft: *result = HTBOTTOMLEFT; break;
case Window::HitTestResult::Left: *result = HTLEFT; break;
case Window::HitTestResult::TopLeft: *result = HTTOPLEFT; break;
case Window::HitTestResult::None:
default: *result = HTTRANSPARENT; break;
};
} return true;
case WM_NCRBUTTONUP: {
SendMessage(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam);
} return true;
}
return false;
}
bool EventFilter::mainWindowEvent(
HWND hWnd,
UINT msg,
@ -92,6 +165,12 @@ bool EventFilter::mainWindowEvent(
}
}
if (!Core::App().settings().nativeWindowFrame()) {
if (customWindowFrameEvent(hWnd, msg, wParam, lParam, result)) {
return true;
}
}
switch (msg) {
case WM_TIMECHANGE: {
@ -124,40 +203,6 @@ bool EventFilter::mainWindowEvent(
}
} return false;
case WM_NCPAINT: {
if (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8) return false;
if (result) *result = 0;
} return true;
case WM_NCCALCSIZE: {
WINDOWPLACEMENT wp;
wp.length = sizeof(WINDOWPLACEMENT);
if (GetWindowPlacement(hWnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED) {
LPNCCALCSIZE_PARAMS params = (LPNCCALCSIZE_PARAMS)lParam;
LPRECT r = (wParam == TRUE) ? &params->rgrc[0] : (LPRECT)lParam;
HMONITOR hMonitor = MonitorFromPoint({ (r->left + r->right) / 2, (r->top + r->bottom) / 2 }, MONITOR_DEFAULTTONEAREST);
if (hMonitor) {
MONITORINFO mi;
mi.cbSize = sizeof(mi);
if (GetMonitorInfo(hMonitor, &mi)) {
*r = mi.rcWork;
}
}
}
if (result) *result = 0;
return true;
}
case WM_NCACTIVATE: {
if (IsCompositionEnabled()) {
const auto res = DefWindowProc(hWnd, msg, wParam, -1);
if (result) *result = res;
} else {
// Thanks https://github.com/melak47/BorderlessWindow
if (result) *result = 1;
}
} return true;
case WM_WINDOWPOSCHANGING:
case WM_WINDOWPOSCHANGED: {
WINDOWPLACEMENT wp;
@ -182,7 +227,7 @@ bool EventFilter::mainWindowEvent(
} else {
_window->positionUpdated();
}
_window->psUpdateMargins();
_window->updateCustomMargins();
const auto changes = (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXIMIZED) ? Change::Hidden : (Change::Resized | Change::Shown);
_window->shadowsUpdate(changes);
}
@ -199,34 +244,6 @@ bool EventFilter::mainWindowEvent(
_window->positionUpdated();
} return false;
case WM_NCHITTEST: {
if (!result) return false;
POINTS p = MAKEPOINTS(lParam);
RECT r;
GetWindowRect(hWnd, &r);
auto res = _window->hitTest(QPoint(p.x - r.left + _window->deltaLeft(), p.y - r.top + _window->deltaTop()));
switch (res) {
case Window::HitTestResult::Client:
case Window::HitTestResult::SysButton: *result = HTCLIENT; break;
case Window::HitTestResult::Caption: *result = HTCAPTION; break;
case Window::HitTestResult::Top: *result = HTTOP; break;
case Window::HitTestResult::TopRight: *result = HTTOPRIGHT; break;
case Window::HitTestResult::Right: *result = HTRIGHT; break;
case Window::HitTestResult::BottomRight: *result = HTBOTTOMRIGHT; break;
case Window::HitTestResult::Bottom: *result = HTBOTTOM; break;
case Window::HitTestResult::BottomLeft: *result = HTBOTTOMLEFT; break;
case Window::HitTestResult::Left: *result = HTLEFT; break;
case Window::HitTestResult::TopLeft: *result = HTTOPLEFT; break;
case Window::HitTestResult::None:
default: *result = HTTRANSPARENT; break;
};
} return true;
case WM_NCRBUTTONUP: {
SendMessage(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam);
} return true;
case WM_SYSCOMMAND: {
if (wParam == SC_MOUSEMENU) {
POINTS p = MAKEPOINTS(lParam);

View File

@ -34,6 +34,13 @@ public:
private:
explicit EventFilter(not_null<MainWindow*> window);
bool customWindowFrameEvent(
HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam,
LRESULT *result);
not_null<MainWindow*> _window;
bool _sessionLoggedOff = false;

View File

@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/about_box.h"
#include "boxes/confirm_box.h"
#include "platform/platform_specific.h"
#include "platform/platform_window_title.h"
#include "base/platform/base_platform_info.h"
#include "window/window_session_controller.h"
#include "lang/lang_keys.h"
@ -407,6 +408,20 @@ void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
}, taskbar->lifetime());
}
if (Platform::AllowNativeWindowFrameToggle()) {
const auto nativeFrame = addCheckbox(
"Use system window frame",
Core::App().settings().nativeWindowFrame());
nativeFrame->checkedChanges(
) | rpl::filter([](bool checked) {
return (checked != Core::App().settings().nativeWindowFrame());
}) | rpl::start_with_next([=](bool checked) {
Core::App().settings().setNativeWindowFrame(checked);
Core::App().saveSettingsDelayed();
}, nativeFrame->lifetime());
}
if (Platform::AutostartSupported()) {
const auto minimizedToggled = [] {
return cStartMinimized() && !Global::LocalPasscode();

View File

@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/crc32hash.h"
#include "base/call_delayed.h"
#include "ui/toast/toast.h"
#include "ui/widgets/shadow.h"
#include "ui/ui_utility.h"
#include "apiwrap.h"
#include "mainwindow.h"
@ -236,9 +237,14 @@ void MainWindow::init() {
updatePalette();
if ((_title = Platform::CreateTitleWidget(this))) {
_title->init();
if (Platform::AllowNativeWindowFrameToggle()) {
Core::App().settings().nativeWindowFrameChanges(
) | rpl::start_with_next([=](bool native) {
refreshTitleWidget();
recountGeometryConstraints();
}, lifetime());
}
refreshTitleWidget();
initSize();
updateUnreadCounter();
@ -311,9 +317,34 @@ int MainWindow::computeMinHeight() const {
return title + outdated + st::windowMinHeight;
}
void MainWindow::initSize() {
void MainWindow::refreshTitleWidget() {
if (Platform::AllowNativeWindowFrameToggle()
&& Core::App().settings().nativeWindowFrame()) {
_title.destroy();
if (Platform::NativeTitleRequiresShadow()) {
_titleShadow.create(this);
_titleShadow->show();
}
} else if ((_title = Platform::CreateTitleWidget(this))) {
_title->show();
_title->init();
_titleShadow.destroy();
}
}
void MainWindow::updateMinimumSize() {
setMinimumWidth(computeMinWidth());
setMinimumHeight(computeMinHeight());
}
void MainWindow::recountGeometryConstraints() {
updateMinimumSize();
updateControlsGeometry();
fixOrder();
}
void MainWindow::initSize() {
updateMinimumSize();
auto position = cWindowPos();
DEBUG_LOG(("Window Pos: Initializing first %1, %2, %3, %4 (maximized %5)").arg(position.x).arg(position.y).arg(position.w).arg(position.h).arg(Logs::b(position.maximized)));
@ -425,6 +456,9 @@ void MainWindow::updateControlsGeometry() {
_title->setGeometry(0, bodyTop, width(), _title->height());
bodyTop += _title->height();
}
if (_titleShadow) {
_titleShadow->setGeometry(0, bodyTop, width(), st::lineWidth);
}
if (_outdated) {
Ui::SendPendingMoveResizeEvents(_outdated.data());
_outdated->resizeToWidth(width());

View File

@ -21,6 +21,7 @@ class Account;
namespace Ui {
class BoxContent;
class PlainShadow;
} // namespace Ui
namespace Window {
@ -80,6 +81,8 @@ public:
virtual void updateTrayMenu(bool force = false) {
}
virtual void fixOrder() {
}
virtual ~MainWindow();
@ -101,6 +104,7 @@ public:
int computeMinWidth() const;
int computeMinHeight() const;
void recountGeometryConstraints();
virtual void updateControlsGeometry();
public slots:
@ -173,6 +177,8 @@ protected:
void updateUnreadCounter();
private:
void refreshTitleWidget();
void updateMinimumSize();
void updatePalette();
void initSize();
@ -184,6 +190,7 @@ private:
bool _positionInited = false;
object_ptr<TitleWidget> _title = { nullptr };
object_ptr<Ui::PlainShadow> _titleShadow = { nullptr };
object_ptr<Ui::RpWidget> _outdated;
object_ptr<Ui::RpWidget> _body;
object_ptr<TWidget> _rightColumn = { nullptr };

View File

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_updates.h"
#include "core/application.h"
#include "core/click_handler_types.h"
#include "platform/platform_window_title.h"
#include "main/main_account.h"
#include "main/main_domain.h"
#include "main/main_session.h"
@ -239,6 +240,13 @@ void Controller::showSettings() {
_widget.showSettings();
}
int Controller::verticalShadowTop() const {
return (Platform::NativeTitleRequiresShadow()
&& Core::App().settings().nativeWindowFrame())
? st::lineWidth
: 0;
}
void Controller::showToast(const QString &text) {
Ui::Toast::Show(_widget.bodyWidget(), text);
}
@ -255,9 +263,7 @@ void Controller::showRightColumn(object_ptr<TWidget> widget) {
}
void Controller::sideBarChanged() {
_widget.setMinimumWidth(_widget.computeMinWidth());
_widget.updateControlsGeometry();
_widget.fixOrder();
_widget.recountGeometryConstraints();
}
void Controller::activate() {

View File

@ -48,6 +48,8 @@ public:
void showSettings();
[[nodiscard]] int verticalShadowTop() const;
template <typename BoxType>
QPointer<BoxType> show(
object_ptr<BoxType> content,

@ -1 +1 @@
Subproject commit 09918f0133ce0070000b9ca2a798057e6ad8bd5d
Subproject commit aed9fe649bc150d8f4c1404b61c6b8bd56192d1b