Add possibility to enable native window frame to Ui::Window
This commit is contained in:
parent
95cafc5064
commit
7a71876124
12 changed files with 229 additions and 54 deletions
|
|
@ -253,6 +253,7 @@ elseif(LINUX)
|
|||
target_link_libraries(lib_ui
|
||||
PUBLIC
|
||||
desktop-app::lib_waylandshells
|
||||
desktop-app::external_kwayland
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
|
|||
|
|
@ -24,23 +24,71 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include <private/qwaylandwindow_p.h>
|
||||
#include <private/qwaylandshellsurface_p.h>
|
||||
|
||||
#include <connection_thread.h>
|
||||
#include <registry.h>
|
||||
|
||||
Q_DECLARE_METATYPE(QMargins);
|
||||
|
||||
using QtWaylandClient::QWaylandIntegration;
|
||||
using QtWaylandClient::QWaylandWindow;
|
||||
using namespace KWayland::Client;
|
||||
|
||||
namespace Ui {
|
||||
namespace Platform {
|
||||
|
||||
WaylandIntegration::WaylandIntegration() {
|
||||
struct WaylandIntegration::Private {
|
||||
std::unique_ptr<ConnectionThread> connection;
|
||||
Registry registry;
|
||||
QEventLoop interfacesLoop;
|
||||
bool interfacesAnnounced = false;
|
||||
};
|
||||
|
||||
WaylandIntegration::WaylandIntegration()
|
||||
: _private(std::make_unique<Private>()) {
|
||||
_private->connection = std::unique_ptr<ConnectionThread>{
|
||||
ConnectionThread::fromApplication(),
|
||||
};
|
||||
|
||||
_private->registry.create(_private->connection.get());
|
||||
_private->registry.setup();
|
||||
|
||||
QObject::connect(
|
||||
_private->connection.get(),
|
||||
&ConnectionThread::connectionDied,
|
||||
&_private->registry,
|
||||
&Registry::destroy);
|
||||
|
||||
QObject::connect(
|
||||
&_private->registry,
|
||||
&Registry::interfacesAnnounced,
|
||||
[=] {
|
||||
_private->interfacesAnnounced = true;
|
||||
if (_private->interfacesLoop.isRunning()) {
|
||||
_private->interfacesLoop.quit();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
WaylandIntegration::~WaylandIntegration() = default;
|
||||
|
||||
WaylandIntegration *WaylandIntegration::Instance() {
|
||||
if (!::Platform::IsWayland()) return nullptr;
|
||||
static WaylandIntegration instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
void WaylandIntegration::waitForInterfaceAnnounce() {
|
||||
Expects(!_private->interfacesLoop.isRunning());
|
||||
if (!_private->interfacesAnnounced) {
|
||||
_private->interfacesLoop.exec();
|
||||
}
|
||||
}
|
||||
|
||||
bool WaylandIntegration::xdgDecorationSupported() {
|
||||
return _private->registry.hasInterface(
|
||||
Registry::Interface::XdgDecorationUnstableV1);
|
||||
}
|
||||
|
||||
bool WaylandIntegration::windowExtentsSupported() {
|
||||
// initialize shell integration before querying
|
||||
if (const auto integration = static_cast<QWaylandIntegration*>(
|
||||
|
|
|
|||
|
|
@ -14,15 +14,21 @@ namespace Platform {
|
|||
|
||||
class WaylandIntegration {
|
||||
public:
|
||||
static WaylandIntegration *Instance();
|
||||
[[nodiscard]] static WaylandIntegration *Instance();
|
||||
|
||||
bool windowExtentsSupported();
|
||||
void waitForInterfaceAnnounce();
|
||||
[[nodiscard]] bool xdgDecorationSupported();
|
||||
[[nodiscard]] bool windowExtentsSupported();
|
||||
void setWindowExtents(QWindow *window, const QMargins &extents);
|
||||
void unsetWindowExtents(QWindow *window);
|
||||
bool showWindowMenu(QWindow *window);
|
||||
|
||||
private:
|
||||
WaylandIntegration();
|
||||
~WaylandIntegration();
|
||||
|
||||
struct Private;
|
||||
const std::unique_ptr<Private> _private;
|
||||
};
|
||||
|
||||
} // namespace Platform
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
namespace Ui {
|
||||
namespace Platform {
|
||||
|
||||
struct WaylandIntegration::Private {
|
||||
};
|
||||
|
||||
WaylandIntegration::WaylandIntegration() {
|
||||
}
|
||||
|
||||
|
|
@ -21,6 +24,13 @@ WaylandIntegration *WaylandIntegration::Instance() {
|
|||
return &instance;
|
||||
}
|
||||
|
||||
void WaylandIntegration::waitForInterfaceAnnounce() {
|
||||
}
|
||||
|
||||
bool WaylandIntegration::xdgDecorationSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WaylandIntegration::windowExtentsSupported() {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
//
|
||||
#include "ui/platform/linux/ui_window_linux.h"
|
||||
|
||||
#include "ui/platform/linux/ui_linux_wayland_integration.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace Platform {
|
||||
|
||||
|
|
@ -14,5 +16,11 @@ std::unique_ptr<BasicWindowHelper> CreateSpecialWindowHelper(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool NativeWindowFrameSupported() {
|
||||
const auto waylandIntegration = WaylandIntegration::Instance();
|
||||
return !waylandIntegration
|
||||
|| waylandIntegration->xdgDecorationSupported();
|
||||
}
|
||||
|
||||
} // namespace Platform
|
||||
} // namespace Ui
|
||||
|
|
|
|||
|
|
@ -412,5 +412,9 @@ std::unique_ptr<BasicWindowHelper> CreateSpecialWindowHelper(
|
|||
return std::make_unique<WindowHelper>(window);
|
||||
}
|
||||
|
||||
bool NativeWindowFrameSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Platform
|
||||
} // namespace Ui
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@ void BasicWindowHelper::setTitle(const QString &title) {
|
|||
void BasicWindowHelper::setTitleStyle(const style::WindowTitle &st) {
|
||||
}
|
||||
|
||||
void BasicWindowHelper::setNativeFrame(bool enabled) {
|
||||
}
|
||||
|
||||
void BasicWindowHelper::setMinimumSize(QSize size) {
|
||||
_window->setMinimumSize(size);
|
||||
}
|
||||
|
|
@ -161,17 +164,21 @@ void DefaultWindowHelper::init() {
|
|||
|
||||
rpl::combine(
|
||||
window()->sizeValue(),
|
||||
_title->heightValue()
|
||||
) | rpl::start_with_next([=](QSize size, int titleHeight) {
|
||||
_title->heightValue(),
|
||||
_title->shownValue()
|
||||
) | rpl::start_with_next([=](
|
||||
QSize size,
|
||||
int titleHeight,
|
||||
bool titleShown) {
|
||||
const auto area = resizeArea();
|
||||
|
||||
const auto sizeWithoutMargins = size
|
||||
.shrunkBy({ 0, titleHeight, 0, 0 })
|
||||
.shrunkBy({ 0, titleShown ? titleHeight : 0, 0, 0 })
|
||||
.shrunkBy(area);
|
||||
|
||||
const auto topLeft = QPoint(
|
||||
area.left(),
|
||||
area.top() + titleHeight);
|
||||
area.top() + (titleShown ? titleHeight : 0));
|
||||
|
||||
_body->setGeometry(QRect(topLeft, sizeWithoutMargins));
|
||||
}, _body->lifetime());
|
||||
|
|
@ -233,7 +240,9 @@ bool DefaultWindowHelper::hasShadow() const {
|
|||
}
|
||||
|
||||
QMargins DefaultWindowHelper::resizeArea() const {
|
||||
if (window()->isMaximized() || window()->isFullScreen()) {
|
||||
if (window()->isMaximized()
|
||||
|| window()->isFullScreen()
|
||||
|| _nativeFrame) {
|
||||
return QMargins();
|
||||
}
|
||||
|
||||
|
|
@ -310,16 +319,23 @@ void DefaultWindowHelper::setTitleStyle(const style::WindowTitle &st) {
|
|||
_title->st()->height);
|
||||
}
|
||||
|
||||
void DefaultWindowHelper::setNativeFrame(bool enabled) {
|
||||
_nativeFrame = enabled;
|
||||
window()->windowHandle()->setFlag(Qt::FramelessWindowHint, !enabled);
|
||||
_title->setVisible(!enabled);
|
||||
updateWindowExtents();
|
||||
}
|
||||
|
||||
void DefaultWindowHelper::setMinimumSize(QSize size) {
|
||||
const auto sizeWithMargins = size
|
||||
.grownBy({ 0, _title->height(), 0, 0 })
|
||||
.grownBy({ 0, _title->isVisible() ? _title->height() : 0, 0, 0 })
|
||||
.grownBy(resizeArea());
|
||||
window()->setMinimumSize(sizeWithMargins);
|
||||
}
|
||||
|
||||
void DefaultWindowHelper::setFixedSize(QSize size) {
|
||||
const auto sizeWithMargins = size
|
||||
.grownBy({ 0, _title->height(), 0, 0 })
|
||||
.grownBy({ 0, _title->isVisible() ? _title->height() : 0, 0, 0 })
|
||||
.grownBy(resizeArea());
|
||||
window()->setFixedSize(sizeWithMargins);
|
||||
_title->setResizeEnabled(false);
|
||||
|
|
@ -327,7 +343,7 @@ void DefaultWindowHelper::setFixedSize(QSize size) {
|
|||
|
||||
void DefaultWindowHelper::setGeometry(QRect rect) {
|
||||
window()->setGeometry(rect
|
||||
.marginsAdded({ 0, _title->height(), 0, 0 })
|
||||
.marginsAdded({ 0, _title->isVisible() ? _title->height() : 0, 0, 0 })
|
||||
.marginsAdded(resizeArea()));
|
||||
}
|
||||
|
||||
|
|
@ -376,7 +392,7 @@ void DefaultWindowHelper::paintBorders(QPainter &p) {
|
|||
}
|
||||
|
||||
void DefaultWindowHelper::updateWindowExtents() {
|
||||
if (hasShadow()) {
|
||||
if (hasShadow() && !_nativeFrame) {
|
||||
Platform::SetWindowExtents(
|
||||
window()->windowHandle(),
|
||||
resizeArea());
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ public:
|
|||
[[nodiscard]] virtual not_null<RpWidget*> body();
|
||||
virtual void setTitle(const QString &title);
|
||||
virtual void setTitleStyle(const style::WindowTitle &st);
|
||||
virtual void setNativeFrame(bool enabled);
|
||||
virtual void setMinimumSize(QSize size);
|
||||
virtual void setFixedSize(QSize size);
|
||||
virtual void setStaysOnTop(bool enabled);
|
||||
|
|
@ -67,6 +68,7 @@ public:
|
|||
not_null<RpWidget*> body() override;
|
||||
void setTitle(const QString &title) override;
|
||||
void setTitleStyle(const style::WindowTitle &st) override;
|
||||
void setNativeFrame(bool enabled) override;
|
||||
void setMinimumSize(QSize size) override;
|
||||
void setFixedSize(QSize size) override;
|
||||
void setGeometry(QRect rect) override;
|
||||
|
|
@ -86,6 +88,7 @@ private:
|
|||
const not_null<DefaultTitleWidget*> _title;
|
||||
const not_null<RpWidget*> _body;
|
||||
bool _extentsSet = false;
|
||||
bool _nativeFrame = false;
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -100,5 +103,7 @@ private:
|
|||
return std::make_unique<DefaultWindowHelper>(window);
|
||||
}
|
||||
|
||||
bool NativeWindowFrameSupported();
|
||||
|
||||
} // namespace Platform
|
||||
} // namespace Ui
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ WindowHelper::WindowHelper(not_null<RpWidget*> window)
|
|||
, _handle(GetWindowHandle(window))
|
||||
, _title(Ui::CreateChild<TitleWidget>(window.get()))
|
||||
, _body(Ui::CreateChild<RpWidget>(window.get()))
|
||||
, _shadow(window, st::windowShadowFg->c) {
|
||||
, _shadow(std::in_place, window, st::windowShadowFg->c) {
|
||||
Expects(_handle != nullptr);
|
||||
|
||||
GetNativeFilter()->registerWindow(_handle, this);
|
||||
|
|
@ -172,18 +172,36 @@ void WindowHelper::setTitleStyle(const style::WindowTitle &st) {
|
|||
_title->setStyle(st);
|
||||
}
|
||||
|
||||
void WindowHelper::setNativeFrame(bool enabled) {
|
||||
_nativeFrame = enabled;
|
||||
_title->setVisible(!enabled);
|
||||
if (enabled) {
|
||||
_shadow.reset();
|
||||
} else {
|
||||
_shadow.emplace(window(), st::windowShadowFg->c);
|
||||
_shadow->setResizeEnabled(!fixedSize());
|
||||
}
|
||||
updateMargins();
|
||||
fixMaximizedWindow();
|
||||
}
|
||||
|
||||
void WindowHelper::setMinimumSize(QSize size) {
|
||||
window()->setMinimumSize(size.width(), _title->height() + size.height());
|
||||
const auto titleHeight = _title->isVisible() ? _title->height() : 0;
|
||||
window()->setMinimumSize(size.width(), titleHeight + size.height());
|
||||
}
|
||||
|
||||
void WindowHelper::setFixedSize(QSize size) {
|
||||
window()->setFixedSize(size.width(), _title->height() + size.height());
|
||||
const auto titleHeight = _title->isVisible() ? _title->height() : 0;
|
||||
window()->setFixedSize(size.width(), titleHeight + size.height());
|
||||
_title->setResizeEnabled(false);
|
||||
_shadow.setResizeEnabled(false);
|
||||
if (_shadow) {
|
||||
_shadow->setResizeEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowHelper::setGeometry(QRect rect) {
|
||||
window()->setGeometry(rect.marginsAdded({ 0, _title->height(), 0, 0 }));
|
||||
const auto titleHeight = _title->isVisible() ? _title->height() : 0;
|
||||
window()->setGeometry(rect.marginsAdded({ 0, titleHeight, 0, 0 }));
|
||||
}
|
||||
|
||||
void WindowHelper::showFullScreen() {
|
||||
|
|
@ -205,19 +223,25 @@ void WindowHelper::showNormal() {
|
|||
void WindowHelper::init() {
|
||||
style::PaletteChanged(
|
||||
) | rpl::start_with_next([=] {
|
||||
_shadow.setColor(st::windowShadowFg->c);
|
||||
if (_shadow) {
|
||||
_shadow->setColor(st::windowShadowFg->c);
|
||||
}
|
||||
Ui::ForceFullRepaint(window());
|
||||
}, window()->lifetime());
|
||||
|
||||
rpl::combine(
|
||||
window()->sizeValue(),
|
||||
_title->heightValue()
|
||||
) | rpl::start_with_next([=](QSize size, int titleHeight) {
|
||||
_title->heightValue(),
|
||||
_title->shownValue()
|
||||
) | rpl::start_with_next([=](
|
||||
QSize size,
|
||||
int titleHeight,
|
||||
bool titleShown) {
|
||||
_body->setGeometry(
|
||||
0,
|
||||
titleHeight,
|
||||
titleShown ? titleHeight : 0,
|
||||
size.width(),
|
||||
size.height() - titleHeight);
|
||||
size.height() - (titleShown ? titleHeight : 0));
|
||||
}, _body->lifetime());
|
||||
|
||||
updateMargins();
|
||||
|
|
@ -256,22 +280,27 @@ bool WindowHelper::handleNativeEvent(
|
|||
if (LOWORD(wParam) == WA_CLICKACTIVE) {
|
||||
Ui::MarkInactivePress(window(), true);
|
||||
}
|
||||
if (LOWORD(wParam) != WA_INACTIVE) {
|
||||
_shadow.update(WindowShadow::Change::Activate);
|
||||
} else {
|
||||
_shadow.update(WindowShadow::Change::Deactivate);
|
||||
if (_shadow) {
|
||||
if (LOWORD(wParam) != WA_INACTIVE) {
|
||||
_shadow->update(WindowShadow::Change::Activate);
|
||||
} else {
|
||||
_shadow->update(WindowShadow::Change::Deactivate);
|
||||
}
|
||||
}
|
||||
window()->update();
|
||||
} return false;
|
||||
|
||||
case WM_NCPAINT: {
|
||||
if (::Platform::IsWindows8OrGreater()) {
|
||||
if (::Platform::IsWindows8OrGreater() || _nativeFrame) {
|
||||
return false;
|
||||
}
|
||||
if (result) *result = 0;
|
||||
} return true;
|
||||
|
||||
case WM_NCCALCSIZE: {
|
||||
if (_nativeFrame) {
|
||||
return false;
|
||||
}
|
||||
WINDOWPLACEMENT wp;
|
||||
wp.length = sizeof(WINDOWPLACEMENT);
|
||||
if (GetWindowPlacement(_handle, &wp)
|
||||
|
|
@ -315,6 +344,9 @@ bool WindowHelper::handleNativeEvent(
|
|||
} return true;
|
||||
|
||||
case WM_NCACTIVATE: {
|
||||
if (_nativeFrame) {
|
||||
return false;
|
||||
}
|
||||
if (IsCompositionEnabled()) {
|
||||
const auto res = DefWindowProc(_handle, msg, wParam, -1);
|
||||
if (result) *result = res;
|
||||
|
|
@ -326,16 +358,18 @@ bool WindowHelper::handleNativeEvent(
|
|||
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
case WM_WINDOWPOSCHANGED: {
|
||||
WINDOWPLACEMENT wp;
|
||||
wp.length = sizeof(WINDOWPLACEMENT);
|
||||
if (GetWindowPlacement(_handle, &wp)
|
||||
&& (wp.showCmd == SW_SHOWMAXIMIZED
|
||||
|| wp.showCmd == SW_SHOWMINIMIZED)) {
|
||||
_shadow.update(WindowShadow::Change::Hidden);
|
||||
} else {
|
||||
_shadow.update(
|
||||
WindowShadow::Change::Moved | WindowShadow::Change::Resized,
|
||||
(WINDOWPOS*)lParam);
|
||||
if (_shadow) {
|
||||
WINDOWPLACEMENT wp;
|
||||
wp.length = sizeof(WINDOWPLACEMENT);
|
||||
if (GetWindowPlacement(_handle, &wp)
|
||||
&& (wp.showCmd == SW_SHOWMAXIMIZED
|
||||
|| wp.showCmd == SW_SHOWMINIMIZED)) {
|
||||
_shadow->update(WindowShadow::Change::Hidden);
|
||||
} else {
|
||||
_shadow->update(
|
||||
WindowShadow::Change::Moved | WindowShadow::Change::Resized,
|
||||
(WINDOWPOS*)lParam);
|
||||
}
|
||||
}
|
||||
} return false;
|
||||
|
||||
|
|
@ -354,30 +388,36 @@ bool WindowHelper::handleNativeEvent(
|
|||
window()->windowHandle()->windowStateChanged(state);
|
||||
}
|
||||
updateMargins();
|
||||
const auto changes = (wParam == SIZE_MINIMIZED
|
||||
|| wParam == SIZE_MAXIMIZED)
|
||||
? WindowShadow::Change::Hidden
|
||||
: (WindowShadow::Change::Resized
|
||||
| WindowShadow::Change::Shown);
|
||||
_shadow.update(changes);
|
||||
if (_shadow) {
|
||||
const auto changes = (wParam == SIZE_MINIMIZED
|
||||
|| wParam == SIZE_MAXIMIZED)
|
||||
? WindowShadow::Change::Hidden
|
||||
: (WindowShadow::Change::Resized
|
||||
| WindowShadow::Change::Shown);
|
||||
_shadow->update(changes);
|
||||
}
|
||||
}
|
||||
} return false;
|
||||
|
||||
case WM_SHOWWINDOW: {
|
||||
const auto style = GetWindowLongPtr(_handle, GWL_STYLE);
|
||||
const auto changes = WindowShadow::Change::Resized
|
||||
| ((wParam && !(style & (WS_MAXIMIZE | WS_MINIMIZE)))
|
||||
? WindowShadow::Change::Shown
|
||||
: WindowShadow::Change::Hidden);
|
||||
_shadow.update(changes);
|
||||
if (_shadow) {
|
||||
const auto style = GetWindowLongPtr(_handle, GWL_STYLE);
|
||||
const auto changes = WindowShadow::Change::Resized
|
||||
| ((wParam && !(style & (WS_MAXIMIZE | WS_MINIMIZE)))
|
||||
? WindowShadow::Change::Shown
|
||||
: WindowShadow::Change::Hidden);
|
||||
_shadow->update(changes);
|
||||
}
|
||||
} return false;
|
||||
|
||||
case WM_MOVE: {
|
||||
_shadow.update(WindowShadow::Change::Moved);
|
||||
if (_shadow) {
|
||||
_shadow->update(WindowShadow::Change::Moved);
|
||||
}
|
||||
} return false;
|
||||
|
||||
case WM_NCHITTEST: {
|
||||
if (!result) {
|
||||
if (!result || _nativeFrame) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -389,7 +429,7 @@ bool WindowHelper::handleNativeEvent(
|
|||
p.y - r.top + _marginsDelta.top());
|
||||
if (!window()->rect().contains(mapped)) {
|
||||
*result = HTTRANSPARENT;
|
||||
} else if (!_title->geometry().contains(mapped)) {
|
||||
} else if (!_title->isVisible() || !_title->geometry().contains(mapped)) {
|
||||
*result = HTCLIENT;
|
||||
} else switch (_title->hitTest(_title->pos() + mapped)) {
|
||||
case HitTestResult::Client:
|
||||
|
|
@ -409,6 +449,9 @@ bool WindowHelper::handleNativeEvent(
|
|||
} return true;
|
||||
|
||||
case WM_NCRBUTTONUP: {
|
||||
if (_nativeFrame) {
|
||||
return false;
|
||||
}
|
||||
SendMessage(_handle, WM_SYSCOMMAND, SC_MOUSEMENU, lParam);
|
||||
} return true;
|
||||
|
||||
|
|
@ -519,8 +562,11 @@ void WindowHelper::updateMargins() {
|
|||
_marginsDelta = QMargins();
|
||||
}
|
||||
|
||||
if (_isFullScreen) {
|
||||
if (_isFullScreen || _nativeFrame) {
|
||||
margins = QMargins();
|
||||
if (_nativeFrame) {
|
||||
_marginsDelta = QMargins();
|
||||
}
|
||||
}
|
||||
if (const auto native = QGuiApplication::platformNativeInterface()) {
|
||||
native->setWindowProperty(
|
||||
|
|
@ -573,6 +619,25 @@ void WindowHelper::updateSystemMenu(Qt::WindowState state) {
|
|||
}
|
||||
}
|
||||
|
||||
void WindowHelper::fixMaximizedWindow() {
|
||||
auto r = RECT();
|
||||
GetClientRect(_handle, &r);
|
||||
const auto style = GetWindowLongPtr(_handle, GWL_STYLE);
|
||||
const auto styleEx = GetWindowLongPtr(_handle, GWL_EXSTYLE);
|
||||
AdjustWindowRectEx(&r, style, false, styleEx);
|
||||
if (style & WS_MAXIMIZE) {
|
||||
auto w = RECT();
|
||||
GetWindowRect(_handle, &w);
|
||||
if (const auto hMonitor = MonitorFromRect(&w, MONITOR_DEFAULTTONEAREST)) {
|
||||
MONITORINFO mi;
|
||||
mi.cbSize = sizeof(mi);
|
||||
GetMonitorInfo(hMonitor, &mi);
|
||||
const auto m = mi.rcWork;
|
||||
SetWindowPos(_handle, 0, 0, 0, m.right - m.left - _marginsDelta.left() - _marginsDelta.right(), m.bottom - m.top - _marginsDelta.top() - _marginsDelta.bottom(), SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREPOSITION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
not_null<WindowHelper::NativeFilter*> WindowHelper::GetNativeFilter() {
|
||||
Expects(QCoreApplication::instance() != nullptr);
|
||||
|
||||
|
|
@ -619,5 +684,9 @@ std::unique_ptr<BasicWindowHelper> CreateSpecialWindowHelper(
|
|||
return std::make_unique<WindowHelper>(window);
|
||||
}
|
||||
|
||||
bool NativeWindowFrameSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Platform
|
||||
} // namespace Ui
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ public:
|
|||
not_null<RpWidget*> body() override;
|
||||
void setTitle(const QString &title) override;
|
||||
void setTitleStyle(const style::WindowTitle &st) override;
|
||||
void setNativeFrame(bool enabled) override;
|
||||
void setMinimumSize(QSize size) override;
|
||||
void setFixedSize(QSize size) override;
|
||||
void setGeometry(QRect rect) override;
|
||||
|
|
@ -38,6 +39,7 @@ private:
|
|||
void updateMargins();
|
||||
void updateSystemMenu();
|
||||
void updateSystemMenu(Qt::WindowState state);
|
||||
void fixMaximizedWindow();
|
||||
[[nodiscard]] bool handleNativeEvent(
|
||||
UINT msg,
|
||||
WPARAM wParam,
|
||||
|
|
@ -50,11 +52,12 @@ private:
|
|||
const HWND _handle = nullptr;
|
||||
const not_null<TitleWidget*> _title;
|
||||
const not_null<RpWidget*> _body;
|
||||
WindowShadow _shadow;
|
||||
std::optional<WindowShadow> _shadow;
|
||||
bool _updatingMargins = false;
|
||||
QMargins _marginsDelta;
|
||||
HMENU _menu = nullptr;
|
||||
bool _isFullScreen = false;
|
||||
bool _nativeFrame = false;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ void Window::setTitleStyle(const style::WindowTitle &st) {
|
|||
_helper->setTitleStyle(st);
|
||||
}
|
||||
|
||||
void Window::setNativeFrame(bool enabled) {
|
||||
_helper->setNativeFrame(enabled);
|
||||
}
|
||||
|
||||
void Window::setMinimumSize(QSize size) {
|
||||
_helper->setMinimumSize(size);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public:
|
|||
|
||||
void setTitle(const QString &title);
|
||||
void setTitleStyle(const style::WindowTitle &st);
|
||||
void setNativeFrame(bool enabled);
|
||||
void setMinimumSize(QSize size);
|
||||
void setFixedSize(QSize size);
|
||||
void setStaysOnTop(bool enabled);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue