mirror of
https://github.com/telegramdesktop/tdesktop
synced 2024-12-27 00:53:22 +00:00
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_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";
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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(
|
||||
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) ? ¶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_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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
|
@ -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 };
|
||||
|
@ -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() {
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user