This commit is contained in:
zhuzichu 2023-12-19 18:01:49 +08:00
parent 38ea91964e
commit f973f006d2
4 changed files with 57 additions and 55 deletions

View File

@ -5,6 +5,7 @@
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#pragma comment(lib, "user32.lib") #pragma comment(lib, "user32.lib")
#include <windows.h> #include <windows.h>
static inline QByteArray qtNativeEventType() static inline QByteArray qtNativeEventType()
{ {
static const auto result = "windows_generic_MSG"; static const auto result = "windows_generic_MSG";
@ -26,6 +27,7 @@ static inline bool isCompositionEnabled(){
} }
return false; return false;
} }
#endif #endif
FramelessEventFilter::FramelessEventFilter(QQuickWindow* window){ FramelessEventFilter::FramelessEventFilter(QQuickWindow* window){
@ -183,7 +185,7 @@ void FluFrameless::componentComplete(){
o = o->parent(); o = o->parent();
} }
if(!_window.isNull()){ if(!_window.isNull()){
_window->setFlag(Qt::FramelessWindowHint,true); _window->setFlags(Qt::FramelessWindowHint|Qt::Window|Qt::WindowTitleHint|Qt::WindowMinMaxButtonsHint|Qt::WindowCloseButtonHint);
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
_nativeEvent =new FramelessEventFilter(_window); _nativeEvent =new FramelessEventFilter(_window);
qApp->installNativeEventFilter(_nativeEvent); qApp->installNativeEventFilter(_nativeEvent);
@ -193,24 +195,39 @@ void FluFrameless::componentComplete(){
DWORD style = GetWindowLongPtr(hwnd,GWL_STYLE); DWORD style = GetWindowLongPtr(hwnd,GWL_STYLE);
SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME | WS_CAPTION &~ WS_SYSMENU); SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME | WS_CAPTION &~ WS_SYSMENU);
SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE |SWP_FRAMECHANGED); SetWindowPos(hwnd,nullptr,0,0,0,0,SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE |SWP_FRAMECHANGED);
_stayTop = QQmlProperty(_window,"stayTop");
_stayTop.connectNotifySignal(this,SLOT(_stayTopChange()));
#endif #endif
_stayTop = QQmlProperty(_window,"stayTop");
_stayTop.connectNotifySignal(this,SLOT(_onStayTopChange()));
_screen = QQmlProperty(_window,"screen");
_screen.connectNotifySignal(this,SLOT(_onScreenChanged()));
_window->installEventFilter(this); _window->installEventFilter(this);
} }
} }
void FluFrameless::_stayTopChange(){ void FluFrameless::_onScreenChanged(){
_window->update();
QGuiApplication::processEvents();
}
void FluFrameless::_onStayTopChange(){
bool isStayTop = _stayTop.read().toBool();
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
HWND hwnd = reinterpret_cast<HWND>(_window->winId()); HWND hwnd = reinterpret_cast<HWND>(_window->winId());
DWORD style = GetWindowLongPtr(hwnd,GWL_STYLE); DWORD style = GetWindowLongPtr(hwnd,GWL_STYLE);
SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME | WS_CAPTION &~ WS_SYSMENU); SetWindowLongPtr(hwnd, GWL_STYLE, style | WS_THICKFRAME | WS_CAPTION &~ WS_SYSMENU);
if(isStayTop){
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}else{
SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
#else
_window->setFlag(Qt::WindowStaysOnTopHint,isStayTop)
#endif #endif
} }
FluFrameless::~FluFrameless(){ FluFrameless::~FluFrameless(){
if (!_window.isNull()) { if (!_window.isNull()) {
_window->setFlag(Qt::FramelessWindowHint,false); _window->setFlags(Qt::Window);
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
qApp->removeNativeEventFilter(_nativeEvent); qApp->removeNativeEventFilter(_nativeEvent);
#endif #endif

View File

@ -6,7 +6,6 @@
#include <QtQml/qqml.h> #include <QtQml/qqml.h>
#include <QAbstractNativeEventFilter> #include <QAbstractNativeEventFilter>
#include <QQmlProperty> #include <QQmlProperty>
#include "stdafx.h"
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
using QT_NATIVE_EVENT_RESULT_TYPE = qintptr; using QT_NATIVE_EVENT_RESULT_TYPE = qintptr;
@ -39,11 +38,13 @@ protected:
bool eventFilter(QObject *obj, QEvent *event) override; bool eventFilter(QObject *obj, QEvent *event) override;
private: private:
void updateCursor(int edges); void updateCursor(int edges);
Q_SLOT void _stayTopChange(); Q_SLOT void _onStayTopChange();
Q_SLOT void _onScreenChanged();
private: private:
QPointer<QQuickWindow> _window = nullptr; QPointer<QQuickWindow> _window = nullptr;
FramelessEventFilter* _nativeEvent = nullptr; FramelessEventFilter* _nativeEvent = nullptr;
QQmlProperty _stayTop; QQmlProperty _stayTop;
QQmlProperty _screen;
}; };
#endif // FLUFRAMELESS_H #endif // FLUFRAMELESS_H

View File

@ -53,15 +53,11 @@ Window {
signal initArgument(var argument) signal initArgument(var argument)
signal firstVisible() signal firstVisible()
id:window id:window
flags: Qt.Window | Qt.WindowTitleHint | Qt.WindowSystemMenuHint | Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint
maximumWidth: fixSize ? width : 16777215 maximumWidth: fixSize ? width : 16777215
maximumHeight: fixSize ? height : 16777215 maximumHeight: fixSize ? height : 16777215
minimumWidth: fixSize ? width : 0 minimumWidth: fixSize ? width : 0
minimumHeight: fixSize ? height : 0 minimumHeight: fixSize ? height : 0
color:"transparent" color:"transparent"
onStayTopChanged: {
d.changedStayTop()
}
Component.onCompleted: { Component.onCompleted: {
useSystemAppBar = FluApp.useSystemAppBar useSystemAppBar = FluApp.useSystemAppBar
if(!useSystemAppBar){ if(!useSystemAppBar){
@ -89,22 +85,6 @@ Window {
QtObject{ QtObject{
id:d id:d
property bool isFirstVisible: true property bool isFirstVisible: true
function changedStayTop(){
function toggleStayTop(){
if(window.stayTop){
window.flags = window.flags | Qt.WindowStaysOnTopHint
}else{
window.flags = window.flags &~ Qt.WindowStaysOnTopHint
}
}
if(window.visibility === Window.Maximized){
window.visibility = Window.Windowed
toggleStayTop()
window.visibility = Window.Maximized
}else{
toggleStayTop()
}
}
} }
Connections{ Connections{
target: window target: window
@ -196,13 +176,25 @@ Window {
id:loader_frameless id:loader_frameless
} }
Item{ Item{
anchors.fill: parent property int offsetX: {
anchors.margins: { if(window.visibility === Window.Maximized){
if(FluTools.isWin() && !window.useSystemAppBar){ return Math.abs(window.x-Screen.virtualX)
return window.visibility === Window.Maximized ? 8 : 0
} }
return 0 return 0
} }
property int offsetY: {
if(window.visibility === Window.Maximized){
return Math.abs(window.y-Screen.virtualY)
}
return 0
}
anchors{
fill:parent
leftMargin: offsetX
rightMargin: offsetX
topMargin: offsetY
bottomMargin: offsetY
}
onWidthChanged: { onWidthChanged: {
window.appBar.width = width window.appBar.width = width
} }

View File

@ -52,15 +52,11 @@ Window {
signal initArgument(var argument) signal initArgument(var argument)
signal firstVisible() signal firstVisible()
id:window id:window
flags: Qt.Window | Qt.WindowTitleHint | Qt.WindowSystemMenuHint | Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint
maximumWidth: fixSize ? width : 16777215 maximumWidth: fixSize ? width : 16777215
maximumHeight: fixSize ? height : 16777215 maximumHeight: fixSize ? height : 16777215
minimumWidth: fixSize ? width : 0 minimumWidth: fixSize ? width : 0
minimumHeight: fixSize ? height : 0 minimumHeight: fixSize ? height : 0
color:"transparent" color:"transparent"
onStayTopChanged: {
d.changedStayTop()
}
Component.onCompleted: { Component.onCompleted: {
useSystemAppBar = FluApp.useSystemAppBar useSystemAppBar = FluApp.useSystemAppBar
if(!useSystemAppBar){ if(!useSystemAppBar){
@ -88,22 +84,6 @@ Window {
QtObject{ QtObject{
id:d id:d
property bool isFirstVisible: true property bool isFirstVisible: true
function changedStayTop(){
function toggleStayTop(){
if(window.stayTop){
window.flags = window.flags | Qt.WindowStaysOnTopHint
}else{
window.flags = window.flags &~ Qt.WindowStaysOnTopHint
}
}
if(window.visibility === Window.Maximized){
window.visibility = Window.Windowed
toggleStayTop()
window.visibility = Window.Maximized
}else{
toggleStayTop()
}
}
} }
Connections{ Connections{
target: window target: window
@ -195,13 +175,25 @@ Window {
id:loader_frameless id:loader_frameless
} }
Item{ Item{
anchors.fill: parent property int offsetX: {
anchors.margins: { if(window.visibility === Window.Maximized){
if(FluTools.isWin() && !window.useSystemAppBar){ return Math.abs(window.x-Screen.virtualX)
return window.visibility === Window.Maximized ? 8 : 0
} }
return 0 return 0
} }
property int offsetY: {
if(window.visibility === Window.Maximized){
return Math.abs(window.y-Screen.virtualY)
}
return 0
}
anchors{
fill:parent
leftMargin: offsetX
rightMargin: offsetX
topMargin: offsetY
bottomMargin: offsetY
}
onWidthChanged: { onWidthChanged: {
window.appBar.width = width window.appBar.width = width
} }