Skip to content

Commit

Permalink
Allow Ui::Window to become fullscreen.
Browse files Browse the repository at this point in the history
  • Loading branch information
john-preston committed Aug 12, 2020
1 parent 608b25b commit 3d5108a
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 27 deletions.
1 change: 1 addition & 0 deletions ui/colors.palette
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,7 @@ notificationBg: windowBg; // custom notification window background
// calls
callBg: #26282cf2; // old phone call popup background
callBgOpaque: #1b1f23 | callBg; // phone call popup background
callBgButton: #1b1f2356 | callBg; // phone call window control buttons bg
callNameFg: #ffffff; // phone call popup name text
callFingerprintBg: #00000066; // phone call popup emoji fingerprint background
callStatusFg: #aaabac; // phone call popup status text
Expand Down
60 changes: 50 additions & 10 deletions ui/platform/ui_platform_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
#include "ui/platform/ui_platform_window.h"

#include "ui/rp_widget.h"
#include "ui/widgets/window.h"

#include <QtGui/QWindow>
#include <QtGui/QtEvents>
Expand Down Expand Up @@ -41,34 +41,74 @@ void BasicWindowHelper::setGeometry(QRect rect) {
_window->setGeometry(rect);
}

void BasicWindowHelper::setBodyTitleArea(Fn<bool(QPoint)> testMethod) {
void BasicWindowHelper::showFullScreen() {
_window->showFullScreen();
}

void BasicWindowHelper::showNormal() {
_window->showNormal();
}

void BasicWindowHelper::setBodyTitleArea(
Fn<WindowTitleHitTestFlags(QPoint)> testMethod) {
Expects(!_bodyTitleAreaTestMethod);

if (!testMethod) {
return;
}
_bodyTitleAreaTestMethod = std::move(testMethod);
if (customBodyTitleAreaHandling()) {
return;
}
body()->events() | rpl::start_with_next([=](not_null<QEvent*> e) {
const auto hitTest = [&] {
return bodyTitleAreaHit(
static_cast<QMouseEvent*>(e.get())->pos());
};
if (e->type() == QEvent::MouseButtonDblClick) {
if (bodyTitleAreaHit(static_cast<QMouseEvent*>(e.get())->pos())) {
_mousePressed = false;
const auto hit = hitTest();
if (hit & WindowTitleHitTestFlag::Maximize) {
const auto state = _window->windowState();
if (state & Qt::WindowMaximized) {
_window->setWindowState(state & ~Qt::WindowMaximized);
} else {
_window->setWindowState(state | Qt::WindowMaximized);
}
} else if (hit & WindowTitleHitTestFlag::FullScreen) {
if (_window->isFullScreen()) {
showNormal();
} else {
showFullScreen();
}
}
} else if (e->type() == QEvent::MouseButtonRelease) {
_mousePressed = false;
} else if (e->type() == QEvent::MouseButtonPress
&& (static_cast<QMouseEvent*>(e.get())->button()
== Qt::LeftButton)) {
_mousePressed = true;

#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
#ifndef Q_OS_MAC // On macOS startSystemMove() doesn't work from here.
} else if (e->type() == QEvent::MouseMove) {
const auto mouseEvent = static_cast<QMouseEvent*>(e.get());
if (bodyTitleAreaHit(mouseEvent->pos())
&& (mouseEvent->buttons() & Qt::LeftButton)) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) || defined DESKTOP_APP_QT_PATCHED
if (_mousePressed
#ifndef Q_OS_WIN // We handle fullscreen startSystemMove() only on Windows.
&& !_window->isFullScreen()
#endif // !Q_OS_WIN
&& (hitTest() & WindowTitleHitTestFlag::Move)) {

#ifdef Q_OS_WIN
if (_window->isFullScreen()) {
// On Windows we just jump out of fullscreen
// like we do automatically for dragging a window
// by title bar in a maximized state.
showNormal();
}
#endif // Q_OS_WIN
_mousePressed = false;
_window->windowHandle()->startSystemMove();
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
}
#endif // !Q_OS_MAC
#endif // Qt >= 5.15 || DESKTOP_APP_QT_PATCHED
}
}, body()->lifetime());
}
Expand Down
23 changes: 15 additions & 8 deletions ui/platform/ui_platform_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,51 @@
//
#pragma once

#include "base/flags.h"

namespace style {
struct WindowTitle;
} // namespace style

namespace Ui {

class RpWidget;
enum class WindowTitleHitTestFlag;
using WindowTitleHitTestFlags = base::flags<WindowTitleHitTestFlag>;

namespace Platform {

class BasicWindowHelper {
public:
explicit BasicWindowHelper(not_null<RpWidget*> window);
virtual ~BasicWindowHelper() = default;

[[nodiscard]] virtual not_null<RpWidget*> body();
virtual void setTitle(const QString &title);
virtual void setTitleStyle(const style::WindowTitle &st);
virtual void setMinimumSize(QSize size);
virtual void setFixedSize(QSize size);
virtual void setGeometry(QRect rect);
virtual ~BasicWindowHelper() = default;
virtual void showFullScreen();
virtual void showNormal();

void setBodyTitleArea(Fn<bool(QPoint)> testMethod);
void setBodyTitleArea(Fn<WindowTitleHitTestFlags(QPoint)> testMethod);

protected:
[[nodiscard]] not_null<RpWidget*> window() const {
return _window;
}
[[nodiscard]] bool bodyTitleAreaHit(QPoint point) const {
return _bodyTitleAreaTestMethod && _bodyTitleAreaTestMethod(point);
}
[[nodiscard]] virtual bool customBodyTitleAreaHandling() {
return false;
[[nodiscard]] WindowTitleHitTestFlags bodyTitleAreaHit(
QPoint point) const {
return _bodyTitleAreaTestMethod
? _bodyTitleAreaTestMethod(point)
: WindowTitleHitTestFlag();
}

private:
const not_null<RpWidget*> _window;
Fn<bool(QPoint)> _bodyTitleAreaTestMethod;
Fn<WindowTitleHitTestFlags(QPoint)> _bodyTitleAreaTestMethod;
bool _mousePressed = false;

};

Expand Down
23 changes: 20 additions & 3 deletions ui/platform/win/ui_window_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,22 @@ void WindowHelper::setGeometry(QRect rect) {
window()->setGeometry(rect.marginsAdded({ 0, _title->height(), 0, 0 }));
}

void WindowHelper::showFullScreen() {
if (!_isFullScreen) {
_isFullScreen = true;
updateMargins();
}
window()->showFullScreen();
}

void WindowHelper::showNormal() {
window()->showNormal();
if (_isFullScreen) {
_isFullScreen = false;
updateMargins();
}
}

void WindowHelper::init() {
style::PaletteChanged(
) | rpl::start_with_next([=] {
Expand Down Expand Up @@ -313,9 +329,7 @@ bool WindowHelper::handleNativeEvent(
if (!window()->rect().contains(mapped)) {
*result = HTTRANSPARENT;
} else if (!_title->geometry().contains(mapped)) {
*result = bodyTitleAreaHit(mapped - QPoint(0, _title->height()))
? HTCAPTION
: HTCLIENT;
*result = HTCLIENT;
} else switch (_title->hitTest(_title->pos() + mapped)) {
case HitTestResult::Client:
case HitTestResult::SysButton: *result = HTCLIENT; break;
Expand Down Expand Up @@ -444,6 +458,9 @@ void WindowHelper::updateMargins() {
_marginsDelta = QMargins();
}

if (_isFullScreen) {
margins = QMargins();
}
if (const auto native = QGuiApplication::platformNativeInterface()) {
native->setWindowProperty(
window()->windowHandle()->handle(),
Expand Down
7 changes: 3 additions & 4 deletions ui/platform/win/ui_window_win.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,13 @@ class WindowHelper final : public BasicWindowHelper {
void setMinimumSize(QSize size) override;
void setFixedSize(QSize size) override;
void setGeometry(QRect rect) override;
void showFullScreen() override;
void showNormal() override;

private:
class NativeFilter;
friend class NativeFilter;

bool customBodyTitleAreaHandling() override {
return true;
}

void init();
void updateMargins();
void updateSystemMenu();
Expand All @@ -56,6 +54,7 @@ class WindowHelper final : public BasicWindowHelper {
bool _updatingMargins = false;
QMargins _marginsDelta;
HMENU _menu = nullptr;
bool _isFullScreen = false;

};

Expand Down
11 changes: 10 additions & 1 deletion ui/widgets/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,16 @@ void Window::setGeometry(QRect rect) {
_helper->setGeometry(rect);
}

void Window::setBodyTitleArea(Fn<bool(QPoint)> testMethod) {
void Window::showFullScreen() {
_helper->showFullScreen();
}

void Window::showNormal() {
_helper->showNormal();
}

void Window::setBodyTitleArea(
Fn<WindowTitleHitTestFlags(QPoint)> testMethod) {
_helper->setBodyTitleArea(std::move(testMethod));
}

Expand Down
16 changes: 15 additions & 1 deletion ui/widgets/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#pragma once

#include "ui/rp_widget.h"
#include "base/flags.h"

namespace style {
struct WindowTitle;
Expand All @@ -17,6 +18,17 @@ namespace Platform {
class BasicWindowHelper;
} // namespace Platform

enum class WindowTitleHitTestFlag {
None = 0x00,
Move = 0x01,
Maximize = 0x02,
FullScreen = 0x04,
};
inline constexpr bool is_flag_type(WindowTitleHitTestFlag) {
return true;
}
using WindowTitleHitTestFlags = base::flags<WindowTitleHitTestFlag>;

class Window : public RpWidget {
public:
explicit Window(QWidget *parent = nullptr);
Expand All @@ -30,7 +42,9 @@ class Window : public RpWidget {
void setMinimumSize(QSize size);
void setFixedSize(QSize size);
void setGeometry(QRect rect);
void setBodyTitleArea(Fn<bool(QPoint)> testMethod);
void showFullScreen();
void showNormal();
void setBodyTitleArea(Fn<WindowTitleHitTestFlags(QPoint)> testMethod);

private:
const std::unique_ptr<Platform::BasicWindowHelper> _helper;
Expand Down

0 comments on commit 3d5108a

Please sign in to comment.