improved borderless window

This commit is contained in:
John Preston 2015-01-28 16:11:14 +03:00
parent de784d2bbc
commit 94d1ea7032
5 changed files with 39 additions and 57 deletions

View File

@ -21,6 +21,8 @@
#include "flatbutton.h" #include "flatbutton.h"
#include "pspecific.h" #include "pspecific.h"
#include "application.h"
#include "lang.h" #include "lang.h"
ContextMenu::ContextMenu(QWidget *parent, const style::iconedButton &st) : TWidget(0), ContextMenu::ContextMenu(QWidget *parent, const style::iconedButton &st) : TWidget(0),
@ -241,7 +243,7 @@ void ContextMenu::deleteOnHide() {
void ContextMenu::popup(const QPoint &p) { void ContextMenu::popup(const QPoint &p) {
QPoint w = p - QPoint(st::dropdownPadding.left(), st::dropdownPadding.top()); QPoint w = p - QPoint(st::dropdownPadding.left(), st::dropdownPadding.top());
QRect r = QDesktopWidget().screenGeometry(p); QRect r = App::app() ? App::app()->desktop()->screenGeometry(p) : QDesktopWidget().screenGeometry(p);
if (w.x() + width() - st::dropdownPadding.right() > r.x() + r.width()) { if (w.x() + width() - st::dropdownPadding.right() > r.x() + r.width()) {
w.setX(r.x() + r.width() - width() + st::dropdownPadding.right()); w.setX(r.x() + r.width() - width() + st::dropdownPadding.right());
} }

View File

@ -24,7 +24,6 @@ namespace {
namespace style { namespace style {
FontData::FontData(uint32 size, uint32 flags, uint32 family, Font *other) : f(_fontFamilies[family]), m(f), _size(size), _flags(flags), _family(family) { FontData::FontData(uint32 size, uint32 flags, uint32 family, Font *other) : f(_fontFamilies[family]), m(f), _size(size), _flags(flags), _family(family) {
// f.setStyleStrategy(QFont::NoAntialias);
if (other) { if (other) {
memcpy(modified, other, sizeof(modified)); memcpy(modified, other, sizeof(modified));
} else { } else {

View File

@ -89,7 +89,7 @@ _saveMsgStarted(0), _saveMsgOpacity(0)
void MediaView::moveToScreen() { void MediaView::moveToScreen() {
QPoint wndCenter(App::wnd()->x() + App::wnd()->width() / 2, App::wnd()->y() + App::wnd()->height() / 2); QPoint wndCenter(App::wnd()->x() + App::wnd()->width() / 2, App::wnd()->y() + App::wnd()->height() / 2);
_avail = QDesktopWidget().screenGeometry(wndCenter); _avail = App::app() ? App::app()->desktop()->screenGeometry(wndCenter) : QDesktopWidget().screenGeometry(wndCenter);
if (_avail != geometry()) { if (_avail != geometry()) {
setGeometry(_avail); setGeometry(_avail);
} }

View File

@ -33,8 +33,6 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
#include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformnativeinterface.h>
#include <dwmapi.h>
#define min(a, b) ((a) < (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) < (b) ? (b) : (a)) #define max(a, b) ((a) < (b) ? (b) : (a))
@ -56,7 +54,6 @@ namespace {
QStringList _initLogs; QStringList _initLogs;
bool frameless = true; bool frameless = true;
bool useDWM = false;
bool useTheme = false; bool useTheme = false;
bool useOpenWith = false; bool useOpenWith = false;
bool useOpenAs = false; bool useOpenAs = false;
@ -207,7 +204,7 @@ namespace {
screenDC = GetDC(0); screenDC = GetDC(0);
if (!screenDC) return false; if (!screenDC) return false;
QRect avail(QDesktopWidget().availableGeometry()); QRect avail(App::app() ? App::app()->desktop()->availableGeometry() : QDesktopWidget().availableGeometry());
max_w = avail.width(); max_w = avail.width();
if (max_w < st::wndMinWidth) max_w = st::wndMinWidth; if (max_w < st::wndMinWidth) max_w = st::wndMinWidth;
max_h = avail.height(); max_h = avail.height();
@ -610,15 +607,6 @@ namespace {
QColor _shActive(0, 0, 0), _shInactive(0, 0, 0); QColor _shActive(0, 0, 0), _shInactive(0, 0, 0);
typedef BOOL (FAR STDAPICALLTYPE *f_dwmDefWindowProc)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, _Out_ LRESULT *plResult);
f_dwmDefWindowProc dwmDefWindowProc = 0;
typedef HRESULT (FAR STDAPICALLTYPE *f_dwmSetWindowAttribute)(HWND hWnd, DWORD dwAttribute, _In_ LPCVOID pvAttribute, DWORD cbAttribute);
f_dwmSetWindowAttribute dwmSetWindowAttribute = 0;
typedef HRESULT (FAR STDAPICALLTYPE *f_dwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS *pMarInset);
f_dwmExtendFrameIntoClientArea dwmExtendFrameIntoClientArea = 0;
typedef HRESULT (FAR STDAPICALLTYPE *f_setWindowTheme)(HWND hWnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList); typedef HRESULT (FAR STDAPICALLTYPE *f_setWindowTheme)(HWND hWnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList);
f_setWindowTheme setWindowTheme = 0; f_setWindowTheme setWindowTheme = 0;
@ -657,22 +645,12 @@ namespace {
class _PsInitializer { class _PsInitializer {
public: public:
_PsInitializer() { _PsInitializer() {
setupDWM(); frameless = false;
useDWM = true;
frameless = !useDWM;
setupUx(); setupUx();
setupShell(); setupShell();
setupWtsapi(); setupWtsapi();
} }
void setupDWM() {
HINSTANCE procId = LoadLibrary(L"DWMAPI.DLL");
if (!loadFunction(procId, "DwmDefWindowProc", dwmDefWindowProc)) return;
if (!loadFunction(procId, "DwmSetWindowAttribute", dwmSetWindowAttribute)) return;
if (!loadFunction(procId, "DwmExtendFrameIntoClientArea", dwmExtendFrameIntoClientArea)) return;
useDWM = true;
}
void setupUx() { void setupUx() {
HINSTANCE procId = LoadLibrary(L"UXTHEME.DLL"); HINSTANCE procId = LoadLibrary(L"UXTHEME.DLL");
@ -755,7 +733,6 @@ namespace {
if (LOWORD(wParam) == WA_CLICKACTIVE) { if (LOWORD(wParam) == WA_CLICKACTIVE) {
App::wnd()->inactivePress(true); App::wnd()->inactivePress(true);
} }
Application::wnd()->psUpdateMargins();
if (LOWORD(wParam) != WA_INACTIVE) { if (LOWORD(wParam) != WA_INACTIVE) {
_psShadowWindows.setColor(_shActive); _psShadowWindows.setColor(_shActive);
_psShadowWindows.update(_PsShadowActivate); _psShadowWindows.update(_PsShadowActivate);
@ -768,33 +745,38 @@ namespace {
case WM_NCPAINT: if (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8) return false; *result = 0; return true; case WM_NCPAINT: if (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8) return false; *result = 0; return true;
case WM_NCCALCSIZE: if (!useDWM) return false; { case WM_NCCALCSIZE: {
if (wParam == TRUE) { WINDOWPLACEMENT wp;
wp.length = sizeof(WINDOWPLACEMENT);
if (GetWindowPlacement(hWnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED) {
LPNCCALCSIZE_PARAMS params = (LPNCCALCSIZE_PARAMS)lParam; LPNCCALCSIZE_PARAMS params = (LPNCCALCSIZE_PARAMS)lParam;
params->rgrc[0].left += margins.left() - simpleMargins.left(); LPRECT r = (wParam == TRUE) ? &params->rgrc[0] : (LPRECT)lParam;
params->rgrc[0].top += margins.top() - simpleMargins.top(); HMONITOR hMonitor = MonitorFromPoint({ (r->left + r->right) / 2, (r->top + r->bottom) / 2 }, MONITOR_DEFAULTTONEAREST);
params->rgrc[0].right -= margins.right() - simpleMargins.right(); if (hMonitor) {
params->rgrc[0].bottom -= margins.bottom() - simpleMargins.bottom(); MONITORINFO mi;
} else if (wParam == FALSE) { mi.cbSize = sizeof(mi);
LPRECT rect = (LPRECT)lParam; if (GetMonitorInfo(hMonitor, &mi)) {
*r = mi.rcWork;
rect->left += margins.left() - simpleMargins.left(); }
rect->top += margins.top() - simpleMargins.top(); }
rect->right += margins.right() - simpleMargins.right();
rect->bottom += margins.bottom() - simpleMargins.bottom();
} }
*result = 0; *result = 0;
} return true; return true;
}
case WM_NCACTIVATE: { case WM_NCACTIVATE: {
//Application::wnd()->psUpdateMargins();
*result = DefWindowProc(hWnd, msg, wParam, -1); *result = DefWindowProc(hWnd, msg, wParam, -1);
//Application::wnd()->repaint();
} return true; } return true;
case WM_WINDOWPOSCHANGING: case WM_WINDOWPOSCHANGING:
case WM_WINDOWPOSCHANGED: { case WM_WINDOWPOSCHANGED: {
_psShadowWindows.update(_PsShadowMoved | _PsShadowResized, (WINDOWPOS*)lParam); WINDOWPLACEMENT wp;
wp.length = sizeof(WINDOWPLACEMENT);
if (GetWindowPlacement(hWnd, &wp) && (wp.showCmd == SW_SHOWMAXIMIZED || wp.showCmd == SW_SHOWMINIMIZED)) {
_psShadowWindows.update(_PsShadowHidden);
} else {
_psShadowWindows.update(_PsShadowMoved | _PsShadowResized, (WINDOWPOS*)lParam);
}
} return false; } return false;
case WM_SIZE: { case WM_SIZE: {
@ -811,6 +793,7 @@ namespace {
} else { } else {
App::wnd()->psUpdatedPosition(); App::wnd()->psUpdatedPosition();
} }
App::wnd()->psUpdateMargins();
int changes = (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXIMIZED) ? _PsShadowHidden : (_PsShadowResized | _PsShadowShown); int changes = (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXIMIZED) ? _PsShadowHidden : (_PsShadowResized | _PsShadowShown);
_psShadowWindows.update(changes); _psShadowWindows.update(changes);
} }
@ -1075,7 +1058,7 @@ void PsMainWindow::psInitSize() {
pos.w = st::wndDefWidth; pos.w = st::wndDefWidth;
pos.h = st::wndDefHeight; pos.h = st::wndDefHeight;
} }
QRect avail(QDesktopWidget().availableGeometry()); QRect avail(App::app() ? App::app()->desktop()->availableGeometry() : QDesktopWidget().availableGeometry());
bool maximized = false; bool maximized = false;
QRect geom(avail.x() + (avail.width() - st::wndDefWidth) / 2, avail.y() + (avail.height() - st::wndDefHeight) / 2, st::wndDefWidth, st::wndDefHeight); QRect geom(avail.x() + (avail.width() - st::wndDefWidth) / 2, avail.y() + (avail.height() - st::wndDefHeight) / 2, st::wndDefWidth, st::wndDefHeight);
if (pos.w && pos.h) { if (pos.w && pos.h) {
@ -1195,7 +1178,7 @@ void PsMainWindow::psFirstShow() {
} }
bool PsMainWindow::psHandleTitle() { bool PsMainWindow::psHandleTitle() {
return useDWM; return true;
} }
void PsMainWindow::psInitSysMenu() { void PsMainWindow::psInitSysMenu() {
@ -1248,7 +1231,7 @@ void PsMainWindow::psUpdateSysMenu(Qt::WindowState state) {
} }
void PsMainWindow::psUpdateMargins() { void PsMainWindow::psUpdateMargins() {
if (!useDWM) return; if (!ps_hWnd) return;
RECT r, a; RECT r, a;
@ -1257,7 +1240,7 @@ void PsMainWindow::psUpdateMargins() {
LONG style = GetWindowLong(ps_hWnd, GWL_STYLE), styleEx = GetWindowLong(ps_hWnd, GWL_EXSTYLE); LONG style = GetWindowLong(ps_hWnd, GWL_STYLE), styleEx = GetWindowLong(ps_hWnd, GWL_EXSTYLE);
AdjustWindowRectEx(&a, style, false, styleEx); AdjustWindowRectEx(&a, style, false, styleEx);
simpleMargins = QMargins(a.left - r.left, a.top - r.top, r.right - a.right, r.bottom - a.bottom); QMargins 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);
@ -1274,23 +1257,22 @@ void PsMainWindow::psUpdateMargins() {
dleft = w.left - m.left; dleft = w.left - m.left;
dtop = w.top - m.top; dtop = w.top - m.top;
margins.setLeft(simpleMargins.left() - w.left + m.left); margins.setLeft(margins.left() - w.left + m.left);
margins.setRight(simpleMargins.right() - m.right + w.right); margins.setRight(margins.right() - m.right + w.right);
margins.setBottom(simpleMargins.bottom() - m.bottom + w.bottom); margins.setBottom(margins.bottom() - m.bottom + w.bottom);
margins.setTop(simpleMargins.top() - w.top + m.top); margins.setTop(margins.top() - w.top + m.top);
} else { } else {
margins = simpleMargins;
dleft = dtop = 0; dleft = dtop = 0;
} }
QPlatformNativeInterface *i = QGuiApplication::platformNativeInterface(); QPlatformNativeInterface *i = QGuiApplication::platformNativeInterface();
i->setWindowProperty(windowHandle()->handle(), "WindowsCustomMargins", QVariant::fromValue<QMargins>(margins)); i->setWindowProperty(windowHandle()->handle(), qsl("WindowsCustomMargins"), QVariant::fromValue<QMargins>(margins));
if (!themeInited) { if (!themeInited) {
themeInited = true; themeInited = true;
if (useTheme) { if (useTheme) {
if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS8) { if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS8) {
setWindowTheme(ps_hWnd, L" ", L" "); setWindowTheme(ps_hWnd, L" ", L" ");
QApplication::setStyle(QStyleFactory::create("Windows")); QApplication::setStyle(QStyleFactory::create(qsl("Windows")));
} }
} }
} }

View File

@ -384,7 +384,6 @@ void Window::stateChanged(Qt::WindowState state) {
updateIsActive((state == Qt::WindowMinimized) ? cOfflineBlurTimeout() : cOnlineFocusTimeout()); updateIsActive((state == Qt::WindowMinimized) ? cOfflineBlurTimeout() : cOnlineFocusTimeout());
psUpdateSysMenu(state); psUpdateSysMenu(state);
psUpdateMargins();
if (state == Qt::WindowMinimized && cWorkMode() == dbiwmTrayOnly) { if (state == Qt::WindowMinimized && cWorkMode() == dbiwmTrayOnly) {
App::wnd()->minimizeToTray(); App::wnd()->minimizeToTray();
} }