parent
d1050e6041
commit
f10b2194e6
|
@ -338,6 +338,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_settings_update_fail" = "Update check failed :(";
|
"lng_settings_update_fail" = "Update check failed :(";
|
||||||
"lng_settings_workmode_tray" = "Show tray icon";
|
"lng_settings_workmode_tray" = "Show tray icon";
|
||||||
"lng_settings_workmode_window" = "Show taskbar 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_auto_start" = "Launch Telegram when system starts";
|
||||||
"lng_settings_start_min" = "Launch minimized";
|
"lng_settings_start_min" = "Launch minimized";
|
||||||
"lng_settings_add_sendto" = "Place Telegram in \"Send to\" menu";
|
"lng_settings_add_sendto" = "Place Telegram in \"Send to\" menu";
|
||||||
|
|
|
@ -105,7 +105,8 @@ QByteArray Settings::serialize() const {
|
||||||
1000000))
|
1000000))
|
||||||
<< qint32(_thirdColumnWidth.current())
|
<< qint32(_thirdColumnWidth.current())
|
||||||
<< qint32(_thirdSectionExtendedBy)
|
<< qint32(_thirdSectionExtendedBy)
|
||||||
<< qint32(_notifyFromAll ? 1 : 0);
|
<< qint32(_notifyFromAll ? 1 : 0)
|
||||||
|
<< qint32(_nativeWindowFrame.current() ? 1 : 0);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -169,6 +170,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||||
qint32 thirdColumnWidth = _thirdColumnWidth.current();
|
qint32 thirdColumnWidth = _thirdColumnWidth.current();
|
||||||
qint32 thirdSectionExtendedBy = _thirdSectionExtendedBy;
|
qint32 thirdSectionExtendedBy = _thirdSectionExtendedBy;
|
||||||
qint32 notifyFromAll = _notifyFromAll ? 1 : 0;
|
qint32 notifyFromAll = _notifyFromAll ? 1 : 0;
|
||||||
|
qint32 nativeWindowFrame = _nativeWindowFrame.current() ? 1 : 0;
|
||||||
|
|
||||||
stream >> themesAccentColors;
|
stream >> themesAccentColors;
|
||||||
if (!stream.atEnd()) {
|
if (!stream.atEnd()) {
|
||||||
|
@ -243,6 +245,9 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||||
>> notifyFromAll;
|
>> notifyFromAll;
|
||||||
dialogsWidthRatio = snap(dialogsWidthRatioInt / 1000000., 0., 1.);
|
dialogsWidthRatio = snap(dialogsWidthRatioInt / 1000000., 0., 1.);
|
||||||
}
|
}
|
||||||
|
if (!stream.atEnd()) {
|
||||||
|
stream >> nativeWindowFrame;
|
||||||
|
}
|
||||||
if (stream.status() != QDataStream::Ok) {
|
if (stream.status() != QDataStream::Ok) {
|
||||||
LOG(("App Error: "
|
LOG(("App Error: "
|
||||||
"Bad data for Core::Settings::constructFromSerialized()"));
|
"Bad data for Core::Settings::constructFromSerialized()"));
|
||||||
|
@ -335,6 +340,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||||
_tabbedSelectorSectionEnabled = false;
|
_tabbedSelectorSectionEnabled = false;
|
||||||
}
|
}
|
||||||
_notifyFromAll = (notifyFromAll == 1);
|
_notifyFromAll = (notifyFromAll == 1);
|
||||||
|
_nativeWindowFrame = (nativeWindowFrame == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::chatWide() const {
|
bool Settings::chatWide() const {
|
||||||
|
|
|
@ -407,6 +407,15 @@ public:
|
||||||
[[nodiscard]] bool notifyFromAll() const {
|
[[nodiscard]] bool notifyFromAll() const {
|
||||||
return _notifyFromAll;
|
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]] static bool ThirdColumnByDefault();
|
||||||
[[nodiscard]] float64 DefaultDialogsWidthRatio();
|
[[nodiscard]] float64 DefaultDialogsWidthRatio();
|
||||||
|
@ -474,6 +483,7 @@ private:
|
||||||
rpl::variable<float64> _dialogsWidthRatio; // per-window
|
rpl::variable<float64> _dialogsWidthRatio; // per-window
|
||||||
rpl::variable<int> _thirdColumnWidth = kDefaultThirdColumnWidth; // p-w
|
rpl::variable<int> _thirdColumnWidth = kDefaultThirdColumnWidth; // p-w
|
||||||
bool _notifyFromAll = true;
|
bool _notifyFromAll = true;
|
||||||
|
rpl::variable<bool> _nativeWindowFrame = false;
|
||||||
|
|
||||||
bool _tabbedReplacedWithInfo = false; // per-window
|
bool _tabbedReplacedWithInfo = false; // per-window
|
||||||
rpl::event_stream<bool> _tabbedReplacedWithInfoValue; // per-window
|
rpl::event_stream<bool> _tabbedReplacedWithInfoValue; // per-window
|
||||||
|
|
|
@ -2177,13 +2177,19 @@ void MainWidget::updateControlsGeometry() {
|
||||||
auto mainSectionWidth = width() - dialogsWidth - thirdSectionWidth;
|
auto mainSectionWidth = width() - dialogsWidth - thirdSectionWidth;
|
||||||
|
|
||||||
_dialogs->setGeometryWithTopMoved({ 0, 0, dialogsWidth, height() }, _contentScrollAddToY);
|
_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) {
|
if (_thirdShadow) {
|
||||||
_thirdShadow->setGeometryToLeft(
|
_thirdShadow->setGeometryToLeft(
|
||||||
width() - thirdSectionWidth - st::lineWidth,
|
width() - thirdSectionWidth - st::lineWidth,
|
||||||
0,
|
shadowTop,
|
||||||
st::lineWidth,
|
st::lineWidth,
|
||||||
height());
|
shadowHeight);
|
||||||
}
|
}
|
||||||
if (_callTopBar) {
|
if (_callTopBar) {
|
||||||
_callTopBar->resizeToWidth(mainSectionWidth);
|
_callTopBar->resizeToWidth(mainSectionWidth);
|
||||||
|
|
|
@ -63,8 +63,6 @@ public:
|
||||||
|
|
||||||
void checkHistoryActivation();
|
void checkHistoryActivation();
|
||||||
|
|
||||||
void fixOrder();
|
|
||||||
|
|
||||||
void sendPaths();
|
void sendPaths();
|
||||||
|
|
||||||
QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) override;
|
QImage iconWithCounter(int size, int count, style::color bg, style::color fg, bool smallIcon) override;
|
||||||
|
@ -79,6 +77,7 @@ public:
|
||||||
|
|
||||||
void showMainMenu();
|
void showMainMenu();
|
||||||
void updateTrayMenu(bool force = false) override;
|
void updateTrayMenu(bool force = false) override;
|
||||||
|
void fixOrder() override;
|
||||||
|
|
||||||
void showSpecialLayer(
|
void showSpecialLayer(
|
||||||
object_ptr<Ui::LayerWidget> layer,
|
object_ptr<Ui::LayerWidget> layer,
|
||||||
|
|
|
@ -22,14 +22,22 @@ void DefaultPreviewWindowFramePaint(QImage &preview, const style::palette &palet
|
||||||
|
|
||||||
namespace Platform {
|
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 QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
|
||||||
if (!DesktopEnvironment::IsUnity()) {
|
return !DesktopEnvironment::IsUnity();
|
||||||
return object_ptr<Window::TitleWidgetQt>(parent);
|
#else // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
||||||
}
|
return false;
|
||||||
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
|
#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() {
|
inline int PreviewTitleHeight() {
|
||||||
|
|
|
@ -32,8 +32,16 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool AllowNativeWindowFrameToggle() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent);
|
object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent);
|
||||||
|
|
||||||
|
inline bool NativeTitleRequiresShadow() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int PreviewTitleHeight();
|
int PreviewTitleHeight();
|
||||||
void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth);
|
void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth);
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
|
|
||||||
|
bool AllowNativeWindowFrameToggle();
|
||||||
object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent);
|
object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent);
|
||||||
|
bool NativeTitleRequiresShadow();
|
||||||
|
|
||||||
int PreviewTitleHeight();
|
int PreviewTitleHeight();
|
||||||
void PreviewWindowFramePaint(QImage &preview, const style::palette &palette, QRect body, int outerWidth);
|
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 {
|
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 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
|
#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() {
|
inline int PreviewTitleHeight() {
|
||||||
|
|
|
@ -112,6 +112,12 @@ MainWindow::MainWindow(not_null<Window::Controller*> controller)
|
||||||
_shadow->setColor(st::windowShadowFg->c);
|
_shadow->setColor(st::windowShadowFg->c);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Core::App().settings().nativeWindowFrameChanges(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
initShadows();
|
||||||
|
validateWindowTheme();
|
||||||
|
fixMaximizedWindow();
|
||||||
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::TaskbarCreated() {
|
void MainWindow::TaskbarCreated() {
|
||||||
|
@ -231,6 +237,10 @@ void MainWindow::workmodeUpdated(DBIWorkMode mode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateWindowIcon() {
|
||||||
|
updateIconCounters();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::unreadCounterChangedHook() {
|
void MainWindow::unreadCounterChangedHook() {
|
||||||
setWindowTitle(titleText());
|
setWindowTitle(titleText());
|
||||||
updateIconCounters();
|
updateIconCounters();
|
||||||
|
@ -294,18 +304,24 @@ void MainWindow::initHook() {
|
||||||
}
|
}
|
||||||
|
|
||||||
psInitSysMenu();
|
psInitSysMenu();
|
||||||
|
|
||||||
_shadow.emplace(this, st::windowShadowFg->c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::initShadows() {
|
void MainWindow::initShadows() {
|
||||||
psUpdateMargins();
|
if (Core::App().settings().nativeWindowFrame()) {
|
||||||
shadowsUpdate(Ui::Platform::WindowShadow::Change::Hidden);
|
_shadow.reset();
|
||||||
|
} else {
|
||||||
|
_shadow.emplace(this, st::windowShadowFg->c);
|
||||||
|
}
|
||||||
|
updateCustomMargins();
|
||||||
|
firstShadowsUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::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);
|
shadowsUpdate(Change::Moved | Change::Resized | Change::Shown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,19 +379,40 @@ void MainWindow::updateSystemMenu(Qt::WindowState state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::psUpdateMargins() {
|
void MainWindow::updateCustomMargins() {
|
||||||
if (!ps_hWnd || _inUpdateMargins) return;
|
if (!ps_hWnd || _inUpdateMargins) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_inUpdateMargins = true;
|
_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);
|
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);
|
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) {
|
if (style & WS_MAXIMIZE) {
|
||||||
RECT w, m;
|
RECT w, m;
|
||||||
GetWindowRect(ps_hWnd, &w);
|
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);
|
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;
|
_deltaLeft = _deltaTop = _deltaRight = _deltaBottom = 0;
|
||||||
}
|
}
|
||||||
|
return margins;
|
||||||
|
}
|
||||||
|
|
||||||
if (const auto native = QGuiApplication::platformNativeInterface()) {
|
void MainWindow::validateWindowTheme() {
|
||||||
native->setWindowProperty(
|
if (IsWindows8OrGreater()) {
|
||||||
windowHandle()->handle(),
|
return;
|
||||||
qsl("WindowsCustomMargins"),
|
} else if (Dlls::SetWindowTheme != nullptr) {
|
||||||
QVariant::fromValue<QMargins>(margins));
|
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()) {
|
void MainWindow::fixMaximizedWindow() {
|
||||||
if (Dlls::SetWindowTheme != nullptr) {
|
auto r = RECT();
|
||||||
Dlls::SetWindowTheme(ps_hWnd, L" ", L" ");
|
GetClientRect(ps_hWnd, &r);
|
||||||
QApplication::setStyle(QStyleFactory::create(qsl("Windows")));
|
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 {
|
HWND MainWindow::psHwnd() const {
|
||||||
|
|
|
@ -31,7 +31,9 @@ public:
|
||||||
|
|
||||||
void psInitSysMenu();
|
void psInitSysMenu();
|
||||||
void updateSystemMenu(Qt::WindowState state);
|
void updateSystemMenu(Qt::WindowState state);
|
||||||
void psUpdateMargins();
|
void updateCustomMargins();
|
||||||
|
|
||||||
|
void updateWindowIcon() override;
|
||||||
|
|
||||||
void psRefreshTaskbarIcon();
|
void psRefreshTaskbarIcon();
|
||||||
|
|
||||||
|
@ -89,8 +91,10 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateIconCounters();
|
void updateIconCounters();
|
||||||
|
QMargins computeCustomMargins();
|
||||||
|
void validateWindowTheme();
|
||||||
void psDestroyIcons();
|
void psDestroyIcons();
|
||||||
|
void fixMaximizedWindow();
|
||||||
|
|
||||||
static UINT _taskbarCreatedMsgId;
|
static UINT _taskbarCreatedMsgId;
|
||||||
|
|
||||||
|
|
|
@ -59,10 +59,18 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool AllowNativeWindowFrameToggle() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
|
inline object_ptr<Window::TitleWidget> CreateTitleWidget(QWidget *parent) {
|
||||||
return object_ptr<TitleWidget>(parent);
|
return object_ptr<TitleWidget>(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool NativeTitleRequiresShadow() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
inline int PreviewTitleHeight() {
|
inline int PreviewTitleHeight() {
|
||||||
return Window::Theme::DefaultPreviewTitleHeight();
|
return Window::Theme::DefaultPreviewTitleHeight();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) ? ¶ms->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(
|
bool EventFilter::mainWindowEvent(
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
UINT msg,
|
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) {
|
switch (msg) {
|
||||||
|
|
||||||
case WM_TIMECHANGE: {
|
case WM_TIMECHANGE: {
|
||||||
|
@ -124,40 +203,6 @@ bool EventFilter::mainWindowEvent(
|
||||||
}
|
}
|
||||||
} return false;
|
} 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) ? ¶ms->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_WINDOWPOSCHANGING:
|
||||||
case WM_WINDOWPOSCHANGED: {
|
case WM_WINDOWPOSCHANGED: {
|
||||||
WINDOWPLACEMENT wp;
|
WINDOWPLACEMENT wp;
|
||||||
|
@ -182,7 +227,7 @@ bool EventFilter::mainWindowEvent(
|
||||||
} else {
|
} else {
|
||||||
_window->positionUpdated();
|
_window->positionUpdated();
|
||||||
}
|
}
|
||||||
_window->psUpdateMargins();
|
_window->updateCustomMargins();
|
||||||
const auto changes = (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXIMIZED) ? Change::Hidden : (Change::Resized | Change::Shown);
|
const auto changes = (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXIMIZED) ? Change::Hidden : (Change::Resized | Change::Shown);
|
||||||
_window->shadowsUpdate(changes);
|
_window->shadowsUpdate(changes);
|
||||||
}
|
}
|
||||||
|
@ -199,34 +244,6 @@ bool EventFilter::mainWindowEvent(
|
||||||
_window->positionUpdated();
|
_window->positionUpdated();
|
||||||
} return false;
|
} 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: {
|
case WM_SYSCOMMAND: {
|
||||||
if (wParam == SC_MOUSEMENU) {
|
if (wParam == SC_MOUSEMENU) {
|
||||||
POINTS p = MAKEPOINTS(lParam);
|
POINTS p = MAKEPOINTS(lParam);
|
||||||
|
|
|
@ -34,6 +34,13 @@ public:
|
||||||
private:
|
private:
|
||||||
explicit EventFilter(not_null<MainWindow*> window);
|
explicit EventFilter(not_null<MainWindow*> window);
|
||||||
|
|
||||||
|
bool customWindowFrameEvent(
|
||||||
|
HWND hWnd,
|
||||||
|
UINT msg,
|
||||||
|
WPARAM wParam,
|
||||||
|
LPARAM lParam,
|
||||||
|
LRESULT *result);
|
||||||
|
|
||||||
not_null<MainWindow*> _window;
|
not_null<MainWindow*> _window;
|
||||||
bool _sessionLoggedOff = false;
|
bool _sessionLoggedOff = false;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/about_box.h"
|
#include "boxes/about_box.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "platform/platform_specific.h"
|
#include "platform/platform_specific.h"
|
||||||
|
#include "platform/platform_window_title.h"
|
||||||
#include "base/platform/base_platform_info.h"
|
#include "base/platform/base_platform_info.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
@ -407,6 +408,20 @@ void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
|
||||||
}, taskbar->lifetime());
|
}, 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()) {
|
if (Platform::AutostartSupported()) {
|
||||||
const auto minimizedToggled = [] {
|
const auto minimizedToggled = [] {
|
||||||
return cStartMinimized() && !Global::LocalPasscode();
|
return cStartMinimized() && !Global::LocalPasscode();
|
||||||
|
|
|
@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/crc32hash.h"
|
#include "base/crc32hash.h"
|
||||||
#include "base/call_delayed.h"
|
#include "base/call_delayed.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
@ -236,9 +237,14 @@ void MainWindow::init() {
|
||||||
|
|
||||||
updatePalette();
|
updatePalette();
|
||||||
|
|
||||||
if ((_title = Platform::CreateTitleWidget(this))) {
|
if (Platform::AllowNativeWindowFrameToggle()) {
|
||||||
_title->init();
|
Core::App().settings().nativeWindowFrameChanges(
|
||||||
|
) | rpl::start_with_next([=](bool native) {
|
||||||
|
refreshTitleWidget();
|
||||||
|
recountGeometryConstraints();
|
||||||
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
refreshTitleWidget();
|
||||||
|
|
||||||
initSize();
|
initSize();
|
||||||
updateUnreadCounter();
|
updateUnreadCounter();
|
||||||
|
@ -311,9 +317,34 @@ int MainWindow::computeMinHeight() const {
|
||||||
return title + outdated + st::windowMinHeight;
|
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());
|
setMinimumWidth(computeMinWidth());
|
||||||
setMinimumHeight(computeMinHeight());
|
setMinimumHeight(computeMinHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::recountGeometryConstraints() {
|
||||||
|
updateMinimumSize();
|
||||||
|
updateControlsGeometry();
|
||||||
|
fixOrder();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::initSize() {
|
||||||
|
updateMinimumSize();
|
||||||
|
|
||||||
auto position = cWindowPos();
|
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)));
|
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());
|
_title->setGeometry(0, bodyTop, width(), _title->height());
|
||||||
bodyTop += _title->height();
|
bodyTop += _title->height();
|
||||||
}
|
}
|
||||||
|
if (_titleShadow) {
|
||||||
|
_titleShadow->setGeometry(0, bodyTop, width(), st::lineWidth);
|
||||||
|
}
|
||||||
if (_outdated) {
|
if (_outdated) {
|
||||||
Ui::SendPendingMoveResizeEvents(_outdated.data());
|
Ui::SendPendingMoveResizeEvents(_outdated.data());
|
||||||
_outdated->resizeToWidth(width());
|
_outdated->resizeToWidth(width());
|
||||||
|
|
|
@ -21,6 +21,7 @@ class Account;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class BoxContent;
|
class BoxContent;
|
||||||
|
class PlainShadow;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
@ -80,6 +81,8 @@ public:
|
||||||
|
|
||||||
virtual void updateTrayMenu(bool force = false) {
|
virtual void updateTrayMenu(bool force = false) {
|
||||||
}
|
}
|
||||||
|
virtual void fixOrder() {
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~MainWindow();
|
virtual ~MainWindow();
|
||||||
|
|
||||||
|
@ -101,6 +104,7 @@ public:
|
||||||
int computeMinWidth() const;
|
int computeMinWidth() const;
|
||||||
int computeMinHeight() const;
|
int computeMinHeight() const;
|
||||||
|
|
||||||
|
void recountGeometryConstraints();
|
||||||
virtual void updateControlsGeometry();
|
virtual void updateControlsGeometry();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -173,6 +177,8 @@ protected:
|
||||||
void updateUnreadCounter();
|
void updateUnreadCounter();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void refreshTitleWidget();
|
||||||
|
void updateMinimumSize();
|
||||||
void updatePalette();
|
void updatePalette();
|
||||||
void initSize();
|
void initSize();
|
||||||
|
|
||||||
|
@ -184,6 +190,7 @@ private:
|
||||||
bool _positionInited = false;
|
bool _positionInited = false;
|
||||||
|
|
||||||
object_ptr<TitleWidget> _title = { nullptr };
|
object_ptr<TitleWidget> _title = { nullptr };
|
||||||
|
object_ptr<Ui::PlainShadow> _titleShadow = { nullptr };
|
||||||
object_ptr<Ui::RpWidget> _outdated;
|
object_ptr<Ui::RpWidget> _outdated;
|
||||||
object_ptr<Ui::RpWidget> _body;
|
object_ptr<Ui::RpWidget> _body;
|
||||||
object_ptr<TWidget> _rightColumn = { nullptr };
|
object_ptr<TWidget> _rightColumn = { nullptr };
|
||||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "api/api_updates.h"
|
#include "api/api_updates.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/click_handler_types.h"
|
#include "core/click_handler_types.h"
|
||||||
|
#include "platform/platform_window_title.h"
|
||||||
#include "main/main_account.h"
|
#include "main/main_account.h"
|
||||||
#include "main/main_domain.h"
|
#include "main/main_domain.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
@ -239,6 +240,13 @@ void Controller::showSettings() {
|
||||||
_widget.showSettings();
|
_widget.showSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Controller::verticalShadowTop() const {
|
||||||
|
return (Platform::NativeTitleRequiresShadow()
|
||||||
|
&& Core::App().settings().nativeWindowFrame())
|
||||||
|
? st::lineWidth
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
void Controller::showToast(const QString &text) {
|
void Controller::showToast(const QString &text) {
|
||||||
Ui::Toast::Show(_widget.bodyWidget(), text);
|
Ui::Toast::Show(_widget.bodyWidget(), text);
|
||||||
}
|
}
|
||||||
|
@ -255,9 +263,7 @@ void Controller::showRightColumn(object_ptr<TWidget> widget) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::sideBarChanged() {
|
void Controller::sideBarChanged() {
|
||||||
_widget.setMinimumWidth(_widget.computeMinWidth());
|
_widget.recountGeometryConstraints();
|
||||||
_widget.updateControlsGeometry();
|
|
||||||
_widget.fixOrder();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::activate() {
|
void Controller::activate() {
|
||||||
|
|
|
@ -48,6 +48,8 @@ public:
|
||||||
|
|
||||||
void showSettings();
|
void showSettings();
|
||||||
|
|
||||||
|
[[nodiscard]] int verticalShadowTop() const;
|
||||||
|
|
||||||
template <typename BoxType>
|
template <typename BoxType>
|
||||||
QPointer<BoxType> show(
|
QPointer<BoxType> show(
|
||||||
object_ptr<BoxType> content,
|
object_ptr<BoxType> content,
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 09918f0133ce0070000b9ca2a798057e6ad8bd5d
|
Subproject commit aed9fe649bc150d8f4c1404b61c6b8bd56192d1b
|
Loading…
Reference in New Issue