ui fixes for macos

This commit is contained in:
Admin 2021-01-03 23:55:04 +03:00
parent e38ff95688
commit 9fa515a9d4
6 changed files with 81 additions and 236 deletions

View file

@ -1,231 +0,0 @@
// This code is a part of Qt-Nice-Frameless-Window
// https://github.com/Bringer-of-Light/Qt-Nice-Frameless-Window
// Licensed by MIT License - https://github.com/Bringer-of-Light/Qt-Nice-Frameless-Window/blob/master/LICENSE
#include "framelesswindow.h"
#ifdef Q_OS_MAC
#include <QDebug>
#include <Cocoa/Cocoa.h>
CFramelessWindow::CFramelessWindow(QWidget *parent)
: QMainWindow(parent),
m_draggableHeight(0),
m_bWinMoving(false),
m_bMousePressed(false),
m_bCloseBtnQuit(true),
m_bNativeSystemBtn(false),
m_bIsCloseBtnEnabled(true),
m_bIsMinBtnEnabled(true),
m_bIsZoomBtnEnabled(true),
m_bTitleBarVisible(false)
{
initUI();
}
//此类用于支持重载系统按钮的行为
//this Objective-c class is used to override the action of sysytem close button and zoom button
//https://stackoverflow.com/questions/27643659/setting-c-function-as-selector-for-nsbutton-produces-no-results
@interface ButtonPasser : NSObject{
}
@property(readwrite) CFramelessWindow* window;
+ (void)closeButtonAction:(id)sender;
- (void)zoomButtonAction:(id)sender;
@end
@implementation ButtonPasser{
}
+ (void)closeButtonAction:(id)sender
{
Q_UNUSED(sender);
ProcessSerialNumber pn;
GetFrontProcess (&pn);
ShowHideProcess(&pn,false);
}
- (void)zoomButtonAction:(id)sender
{
Q_UNUSED(sender);
if (0 == self.window) return;
if (self.window->isMaximized()) self.window->showNormal();
else self.window->showMaximized();
}
@end
void CFramelessWindow::initUI()
{
m_bNativeSystemBtn = false;
//如果当前osx版本老于10.9,则后续代码不可用。转为使用定制的系统按钮,不支持自由缩放窗口及窗口阴影
if (QSysInfo::MV_None == QSysInfo::macVersion())
{
if (QSysInfo::MV_None == QSysInfo::MacintoshVersion) {setWindowFlags(Qt::FramelessWindowHint); return;}
}
if (QSysInfo::MV_10_9 >= QSysInfo::MacintoshVersion) {setWindowFlags(Qt::FramelessWindowHint); return;}
NSView* view = (NSView*)winId();
if (0 == view) {setWindowFlags(Qt::FramelessWindowHint); return;}
NSWindow *window = view.window;
if (0 == window) {setWindowFlags(Qt::FramelessWindowHint); return;}
//设置标题文字和图标为不可见
window.titleVisibility = NSWindowTitleHidden; //MAC_10_10及以上版本支持
//设置标题栏为透明
window.titlebarAppearsTransparent = YES; //MAC_10_10及以上版本支持
//设置不可由标题栏拖动,避免与自定义拖动冲突
[window setMovable:NO]; //MAC_10_6及以上版本支持
//window.movableByWindowBackground = YES;
//设置view扩展到标题栏
window.styleMask |= NSWindowStyleMaskFullSizeContentView; //MAC_10_10及以上版本支持
m_bNativeSystemBtn = true;
ButtonPasser * passer = [[ButtonPasser alloc] init];
passer.window = this;
//重载全屏按钮的行为
//override the action of fullscreen button
NSButton *zoomButton = [window standardWindowButton:NSWindowZoomButton];
[zoomButton setTarget:passer];
[zoomButton setAction:@selector(zoomButtonAction:)];
}
void CFramelessWindow::setCloseBtnQuit(bool bQuit)
{
if (bQuit || !m_bNativeSystemBtn) return;
NSView* view = (NSView*)winId();
if (0 == view) return;
NSWindow *window = view.window;
if (0 == window) return;
//重载关闭按钮的行为
//override the action of close button
//https://stackoverflow.com/questions/27643659/setting-c-function-as-selector-for-nsbutton-produces-no-results
//https://developer.apple.com/library/content/documentation/General/Conceptual/CocoaEncyclopedia/Target-Action/Target-Action.html
NSButton *closeButton = [window standardWindowButton:NSWindowCloseButton];
[closeButton setTarget:[ButtonPasser class]];
[closeButton setAction:@selector(closeButtonAction:)];
}
void CFramelessWindow::setCloseBtnEnabled(bool bEnable)
{
if (!m_bNativeSystemBtn) return;
NSView* view = (NSView*)winId();
if (0 == view) return;
NSWindow *window = view.window;
if (0 == window) return;
m_bIsCloseBtnEnabled = bEnable;
if (bEnable){
[[window standardWindowButton:NSWindowCloseButton] setEnabled:YES];
}else{
[[window standardWindowButton:NSWindowCloseButton] setEnabled:NO];
}
}
void CFramelessWindow::setMinBtnEnabled(bool bEnable)
{
if (!m_bNativeSystemBtn) return;
NSView* view = (NSView*)winId();
if (0 == view) return;
NSWindow *window = view.window;
if (0 == window) return;
m_bIsMinBtnEnabled = bEnable;
if (bEnable){
[[window standardWindowButton:NSWindowMiniaturizeButton] setEnabled:YES];
}else{
[[window standardWindowButton:NSWindowMiniaturizeButton] setEnabled:NO];
}
}
void CFramelessWindow::setZoomBtnEnabled(bool bEnable)
{
if (!m_bNativeSystemBtn) return;
NSView* view = (NSView*)winId();
if (0 == view) return;
NSWindow *window = view.window;
if (0 == window) return;
m_bIsZoomBtnEnabled = bEnable;
if (bEnable){
[[window standardWindowButton:NSWindowZoomButton] setEnabled:YES];
}else{
[[window standardWindowButton:NSWindowZoomButton] setEnabled:NO];
}
}
void CFramelessWindow::setDraggableAreaHeight(int height)
{
if (height < 0) height = 0;
m_draggableHeight = height;
}
void CFramelessWindow::mousePressEvent(QMouseEvent *event)
{
if ((event->button() != Qt::LeftButton) || isMaximized() )
{
return QMainWindow::mousePressEvent(event);
}
int height = size().height();
if (m_draggableHeight > 0) height = m_draggableHeight;
QRect rc;
rc.setRect(0,0,size().width(), height);
if(rc.contains(this->mapFromGlobal(QCursor::pos()))==true)//如果按下的位置
{
m_WindowPos = this->pos();
m_MousePos = event->globalPos();
m_bMousePressed = true;
}
return QMainWindow::mousePressEvent(event);
}
void CFramelessWindow::mouseReleaseEvent(QMouseEvent *event)
{
m_bWinMoving = false;
if ((event->button() == Qt::LeftButton))
{
m_bMousePressed = false;
}
return QMainWindow::mouseReleaseEvent(event);
}
void CFramelessWindow::mouseMoveEvent(QMouseEvent *event)
{
if (!m_bMousePressed) return QMainWindow::mouseMoveEvent(event);
m_bWinMoving = true;
this->move(m_WindowPos + (event->globalPos() - m_MousePos));
return QMainWindow::mouseMoveEvent(event);
}
void CFramelessWindow::resizeEvent(QResizeEvent *event)
{
QMainWindow::resizeEvent(event);
//TODO
// if (!isFullScreen())
// {
// emit restoreFromFullScreen();
// }
}
void CFramelessWindow::onRestoreFromFullScreen()
{
setTitlebarVisible(false);
}
void CFramelessWindow::setTitlebarVisible(bool bTitlebarVisible)
{
if (!m_bNativeSystemBtn) return;
NSView* view = (NSView*)winId();
if (0 == view) return;
NSWindow *window = view.window;
if (0 == window) return;
m_bTitleBarVisible = bTitlebarVisible;
if (bTitlebarVisible)
{
window.styleMask ^= NSWindowStyleMaskFullSizeContentView; //MAC_10_10及以上版本支持
}else{
window.styleMask |= NSWindowStyleMaskFullSizeContentView; //MAC_10_10及以上版本支持
}
}
#endif //Q_OS_MAC

8
client/ui/macos_util.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef OSXUTIL_H
#define OSXUTIL_H
#include <QDialog>
#include <QWidget>
void fixWidget(QWidget *widget);
#endif

48
client/ui/macos_util.mm Normal file
View file

@ -0,0 +1,48 @@
#include <QMainWindow>
#include <Cocoa/Cocoa.h>
#include "macos_util.h"
//this Objective-c class is used to override the action of system close button and zoom button
//https://stackoverflow.com/questions/27643659/setting-c-function-as-selector-for-nsbutton-produces-no-results
@interface ButtonPasser : NSObject{
}
@property(readwrite) QMainWindow* window;
+ (void)closeButtonAction:(id)sender;
- (void)zoomButtonAction:(id)sender;
@end
@implementation ButtonPasser{
}
+ (void)closeButtonAction:(id)sender
{
Q_UNUSED(sender);
ProcessSerialNumber pn;
GetFrontProcess (&pn);
ShowHideProcess(&pn,false);
}
- (void)zoomButtonAction:(id)sender
{
Q_UNUSED(sender);
if (0 == self.window) return;
if (self.window->isMaximized()) self.window->showNormal();
else self.window->showMaximized();
}
@end
void fixWidget(QWidget *widget)
{
NSView *view = (NSView *)widget->winId();
if (0 == view) return;
NSWindow *window = view.window;
if (0 == window) return;
//override the action of close button
//https://stackoverflow.com/questions/27643659/setting-c-function-as-selector-for-nsbutton-produces-no-results
//https://developer.apple.com/library/content/documentation/General/Conceptual/CocoaEncyclopedia/Target-Action/Target-Action.html
// NSButton *closeButton = [window standardWindowButton:NSWindowCloseButton];
// [closeButton setTarget:[ButtonPasser class]];
// [closeButton setAction:@selector(closeButtonAction:)];
[[window standardWindowButton:NSWindowZoomButton] setHidden:YES];
[[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
}

View file

@ -14,8 +14,16 @@
#include "utils.h"
#include "vpnconnection.h"
#ifdef Q_OS_MAC
#include "ui/macos_util.h"
#endif
MainWindow::MainWindow(QWidget *parent) :
#ifdef Q_OS_WIN
CFramelessWindow(parent),
#else
QMainWindow(parent),
#endif
ui(new Ui::MainWindow),
m_settings(new Settings),
m_vpnConnection(nullptr)
@ -26,6 +34,12 @@ MainWindow::MainWindow(QWidget *parent) :
ui->stackedWidget_main->setSpeed(200);
ui->stackedWidget_main->setAnimation(QEasingCurve::Linear);
#ifdef Q_OS_MAC
ui->widget_tittlebar->hide();
ui->stackedWidget_main->move(0,0);
fixWidget(this);
#endif
// Post initialization
if (m_settings->haveAuthData()) {

View file

@ -16,7 +16,12 @@ class MainWindow;
/**
* @brief The MainWindow class - Main application window
*/
#ifdef Q_OS_WIN
class MainWindow : public CFramelessWindow
#else
class MainWindow : public QMainWindow
#endif
{
Q_OBJECT