Allow fixed windows with custom title bar.

This commit is contained in:
John Preston 2019-10-14 13:57:03 +04:00
parent bc62f87f0e
commit c0ce14bb68
11 changed files with 85 additions and 14 deletions

View file

@ -20,7 +20,8 @@ public:
not_null<RpWidget*> body() override;
void setTitle(const QString &title) override;
void setSizeMin(QSize size) override;
void setMinimumSize(QSize size) override;
void setFixedSize(QSize size) override;
void setGeometry(QRect rect) override;
private:

View file

@ -204,12 +204,18 @@ void WindowHelper::toggleCustomTitle(bool visible) {
_window->setWindowTitle(visible ? QString() : _title->text());
}
void WindowHelper::setSizeMin(QSize size) {
void WindowHelper::setMinimumSize(QSize size) {
_window->setMinimumSize(
size.width(),
(_title ? _title->height() : 0) + size.height());
}
void WindowHelper::setFixedSize(QSize size) {
_window->setFixedSize(
size.width(),
(_title ? _title->height() : 0) + size.height());
}
void WindowHelper::setGeometry(QRect rect) {
_window->setGeometry(
rect.marginsAdded({ 0, (_title ? _title->height() : 0), 0, 0 }));

View file

@ -16,7 +16,8 @@ class BasicWindowHelper {
public:
[[nodiscard]] virtual not_null<RpWidget*> body() = 0;
virtual void setTitle(const QString &title) = 0;
virtual void setSizeMin(QSize size) = 0;
virtual void setMinimumSize(QSize size) = 0;
virtual void setFixedSize(QSize size) = 0;
virtual void setGeometry(QRect rect) = 0;
virtual ~BasicWindowHelper() = default;

View file

@ -514,6 +514,10 @@ void WindowShadow::updateWindow(int i, POINT *p, SIZE *s) {
}
}
void WindowShadow::setResizeEnabled(bool enabled) {
_resizeEnabled = enabled;
}
LRESULT CALLBACK WindowShadow::WindowCallback(
HWND hwnd,
UINT msg,
@ -540,6 +544,9 @@ LRESULT WindowShadow::windowCallback(
return 0;
case WM_NCHITTEST: {
if (!_resizeEnabled) {
return HTTRANSPARENT;
}
const auto xPos = GET_X_LPARAM(lParam);
const auto yPos = GET_Y_LPARAM(lParam);
if (hwnd == _handles[0]) {

View file

@ -43,6 +43,7 @@ public:
void setColor(QColor color);
void update(Changes changes, WINDOWPOS *pos = nullptr);
void updateWindow(int i, POINT *p, SIZE *s = nullptr);
void setResizeEnabled(bool enabled);
private:
enum class Direction {
@ -90,6 +91,7 @@ private:
std::vector<BYTE> _colors;
bool _hidden = true;
bool _resizeEnabled = true;
HWND _handles[4] = { nullptr };
HDC _contexts[4] = { nullptr };

View file

@ -38,6 +38,11 @@ not_null<RpWidget*> TitleWidget::window() const {
return static_cast<RpWidget*>(parentWidget());
}
void TitleWidget::setResizeEnabled(bool enabled) {
_resizeEnabled = enabled;
updateControlsVisibility();
}
void TitleWidget::init() {
_minimize->setClickedCallback([=] {
window()->setWindowState(Qt::WindowMinimized);
@ -85,7 +90,10 @@ void TitleWidget::paintEvent(QPaintEvent *e) {
void TitleWidget::updateControlsPosition() {
auto right = 0;
_close->moveToRight(right, 0); right += _close->width();
_maximizeRestore->moveToRight(right, 0); right += _maximizeRestore->width();
_maximizeRestore->moveToRight(right, 0);
if (_resizeEnabled) {
right += _maximizeRestore->width();
}
_minimize->moveToRight(right, 0);
}
@ -95,6 +103,7 @@ void TitleWidget::resizeEvent(QResizeEvent *e) {
}
void TitleWidget::updateControlsVisibility() {
_maximizeRestore->setVisible(_resizeEnabled);
updateControlsPosition();
update();
}

View file

@ -39,7 +39,8 @@ public:
explicit TitleWidget(not_null<RpWidget*> parent);
void setText(const QString &text);
HitTestResult hitTest(QPoint point) const;
[[nodiscard]] HitTestResult hitTest(QPoint point) const;
void setResizeEnabled(bool enabled);
protected:
void paintEvent(QPaintEvent *e) override;
@ -61,6 +62,7 @@ private:
bool _maximizedState = false;
bool _activeState = false;
bool _resizeEnabled = true;
};

View file

@ -99,10 +99,16 @@ void WindowHelper::setTitle(const QString &title) {
_window->setWindowTitle(title);
}
void WindowHelper::setSizeMin(QSize size) {
void WindowHelper::setMinimumSize(QSize size) {
_window->setMinimumSize(size.width(), _title->height() + size.height());
}
void WindowHelper::setFixedSize(QSize size) {
_window->setFixedSize(size.width(), _title->height() + size.height());
_title->setResizeEnabled(false);
_shadow.setResizeEnabled(false);
}
void WindowHelper::setGeometry(QRect rect) {
_window->setGeometry(rect.marginsAdded({ 0, _title->height(), 0, 0 }));
}
@ -133,10 +139,20 @@ void WindowHelper::init() {
_menu = GetSystemMenu(_handle, FALSE);
updateSystemMenu();
const auto handleStateChanged = [=](Qt::WindowState state) {
updateSystemMenu(state);
if (fixedSize() && (state & Qt::WindowMaximized)) {
crl::on_main(_window.get(), [=] {
_window->setWindowState(
_window->windowState() & ~Qt::WindowMaximized);
});
}
};
Ui::Connect(
_window->windowHandle(),
&QWindow::windowStateChanged,
[=](Qt::WindowState state) { updateSystemMenu(state); });
handleStateChanged);
}
bool WindowHelper::handleNativeEvent(
@ -189,6 +205,16 @@ bool WindowHelper::handleNativeEvent(
return true;
}
case WM_NCLBUTTONDBLCLK:
case WM_NCMBUTTONDBLCLK:
case WM_NCRBUTTONDBLCLK:
case WM_NCXBUTTONDBLCLK: {
if (!fixedSize()) {
return false;
}
if (result) *result = 0;
} return true;
case WM_NCACTIVATE: {
if (IsCompositionEnabled()) {
const auto res = DefWindowProc(_handle, msg, wParam, -1);
@ -288,7 +314,7 @@ bool WindowHelper::handleNativeEvent(
} return true;
case WM_SYSCOMMAND: {
if (wParam == SC_MOUSEMENU) {
if (wParam == SC_MOUSEMENU && !fixedSize()) {
POINTS p = MAKEPOINTS(lParam);
updateSystemMenu(_window->windowHandle()->windowState());
TrackPopupMenu(
@ -313,7 +339,9 @@ bool WindowHelper::handleNativeEvent(
_window->setWindowState(Qt::WindowMinimized);
return true;
case SC_MAXIMIZE:
_window->setWindowState(Qt::WindowMaximized);
if (!fixedSize()) {
_window->setWindowState(Qt::WindowMaximized);
}
return true;
case SC_RESTORE:
_window->setWindowState(Qt::WindowNoState);
@ -325,6 +353,10 @@ bool WindowHelper::handleNativeEvent(
return false;
}
bool WindowHelper::fixedSize() const {
return _window->minimumSize() == _window->maximumSize();
}
void WindowHelper::updateMargins() {
if (_updatingMargins) return;

View file

@ -23,7 +23,8 @@ public:
not_null<RpWidget*> body() override;
void setTitle(const QString &title) override;
void setSizeMin(QSize size) override;
void setMinimumSize(QSize size) override;
void setFixedSize(QSize size) override;
void setGeometry(QRect rect) override;
private:
@ -39,6 +40,7 @@ private:
WPARAM wParam,
LPARAM lParam,
LRESULT *result);
[[nodiscard]] bool fixedSize() const;
static not_null<NativeFilter*> GetNativeFilter();

View file

@ -34,11 +34,19 @@ void Window::setTitle(const QString &title) {
}
}
void Window::setSizeMin(QSize size) {
void Window::setMinimumSize(QSize size) {
if (_helper) {
_helper->setSizeMin(size);
_helper->setMinimumSize(size);
} else {
setMinimumSize(size);
RpWidget::setMinimumSize(size);
}
}
void Window::setFixedSize(QSize size) {
if (_helper) {
_helper->setFixedSize(size);
} else {
RpWidget::setFixedSize(size);
}
}

View file

@ -22,7 +22,8 @@ public:
[[nodiscard]] not_null<const RpWidget*> body() const;
void setTitle(const QString &title);
void setSizeMin(QSize size);
void setMinimumSize(QSize size);
void setFixedSize(QSize size);
void setGeometry(QRect rect);
private: