WireGuard for MacOS (#248)
* WireGuard for MacOS * Fix openvpn block-outside-dns
This commit is contained in:
parent
ed5dc7cdfd
commit
35ecb8499d
118 changed files with 5150 additions and 3486 deletions
|
@ -4,20 +4,27 @@
|
|||
|
||||
#include "macosutils.h"
|
||||
#include "logger.h"
|
||||
#include "models/helpmodel.h"
|
||||
#include "qmlengineholder.h"
|
||||
|
||||
#include <objc/message.h>
|
||||
#include <objc/objc.h>
|
||||
|
||||
#include <QFile>
|
||||
#include <QMenuBar>
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <ServiceManagement/ServiceManagement.h>
|
||||
|
||||
namespace {
|
||||
Logger logger(LOG_MACOS, "MacOSUtils");
|
||||
Logger logger("MacOSUtils");
|
||||
}
|
||||
|
||||
// static
|
||||
NSString* MacOSUtils::appId() {
|
||||
NSString* appId = [[NSBundle mainBundle] bundleIdentifier];
|
||||
if (!appId) {
|
||||
// Fallback. When an unsigned/un-notarized app is executed in
|
||||
// command-line mode, it could fail the fetching of its own bundle id.
|
||||
appId = @"org.amnezia.AmneziaVPN";
|
||||
}
|
||||
|
||||
return appId;
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -30,7 +37,9 @@ QString MacOSUtils::computerName() {
|
|||
void MacOSUtils::enableLoginItem(bool startAtBoot) {
|
||||
logger.debug() << "Enabling login-item";
|
||||
|
||||
NSString* appId = [[NSBundle mainBundle] bundleIdentifier];
|
||||
NSString* appId = MacOSUtils::appId();
|
||||
Q_ASSERT(appId);
|
||||
|
||||
NSString* loginItemAppId =
|
||||
QString("%1.login-item").arg(QString::fromNSString(appId)).toNSString();
|
||||
CFStringRef cfs = (__bridge CFStringRef)loginItemAppId;
|
||||
|
@ -46,7 +55,8 @@ bool dockClickHandler(id self, SEL cmd, ...) {
|
|||
Q_UNUSED(cmd);
|
||||
|
||||
logger.debug() << "Dock icon clicked.";
|
||||
QmlEngineHolder::instance()->showWindow();
|
||||
//TODO IMPL FOR AMNEZIA
|
||||
//QmlEngineHolder::instance()->showWindow();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -89,3 +99,102 @@ void MacOSUtils::hideDockIcon() {
|
|||
void MacOSUtils::showDockIcon() {
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the setImage method on NSStatusBarButton with a method that scales
|
||||
* images proportionally before setting.
|
||||
*
|
||||
* The reason for this is that there is a bug in Qt 5.15 that causes status bar
|
||||
* icons to be displayed larger than UI recommendations, and out of proportion
|
||||
* on displays with a device pixel ratio greater than 1 (MacOS Big Sur only).
|
||||
* This bug will not be fixed in Qt open source versions, so we have to resort
|
||||
* to a hack that exchanges the implementation of a method on NSStatusBarButton
|
||||
* with one that correctly scales the icon.
|
||||
*
|
||||
* Original bug (and sample implementation):
|
||||
* https://bugreports.qt.io/browse/QTBUG-88600
|
||||
*/
|
||||
void MacOSUtils::patchNSStatusBarSetImageForBigSur() {
|
||||
Method original = class_getInstanceMethod([NSStatusBarButton class], @selector(setImage:));
|
||||
Method patched = class_getInstanceMethod([NSStatusBarButton class], @selector(setImagePatched:));
|
||||
method_exchangeImplementations(original, patched);
|
||||
}
|
||||
|
||||
@interface NSImageScalingHelper : NSObject
|
||||
/**
|
||||
* Create a proportionally scaled image according to the given target size.
|
||||
*
|
||||
* @param sourceImage The original image to be scaled.
|
||||
* @param targetSize The required size of the image.
|
||||
* @return A scaled image.
|
||||
*/
|
||||
+ (NSImage*)imageByScaling:(NSImage*)sourceImage size:(NSSize)targetSize;
|
||||
@end
|
||||
|
||||
@implementation NSImageScalingHelper
|
||||
+ (NSImage*)imageByScaling:(NSImage*)sourceImage size:(NSSize)targetSize {
|
||||
NSImage* newImage = nil;
|
||||
|
||||
if ([sourceImage isValid]) {
|
||||
NSSize sourceSize = [sourceImage size];
|
||||
|
||||
if (sourceSize.width != 0.0 && sourceSize.height != 0.0) {
|
||||
float scaleFactor = 0.0;
|
||||
float scaledWidth = targetSize.width;
|
||||
float scaledHeight = targetSize.height;
|
||||
|
||||
NSPoint thumbnailPoint = NSZeroPoint;
|
||||
|
||||
if (NSEqualSizes(sourceSize, targetSize) == NO) {
|
||||
float widthFactor = targetSize.width / sourceSize.width;
|
||||
float heightFactor = targetSize.height / sourceSize.height;
|
||||
|
||||
if (widthFactor < heightFactor) {
|
||||
scaleFactor = widthFactor;
|
||||
} else {
|
||||
scaleFactor = heightFactor;
|
||||
}
|
||||
scaledWidth = sourceSize.width * scaleFactor;
|
||||
scaledHeight = sourceSize.height * scaleFactor;
|
||||
|
||||
if (widthFactor < heightFactor) {
|
||||
thumbnailPoint.y = (targetSize.height - scaledHeight) * 0.5;
|
||||
} else {
|
||||
thumbnailPoint.x = (targetSize.width - scaledWidth) * 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
newImage = [[NSImage alloc] initWithSize:targetSize];
|
||||
|
||||
[newImage lockFocus];
|
||||
|
||||
NSRect thumbnailRect;
|
||||
thumbnailRect.origin = thumbnailPoint;
|
||||
thumbnailRect.size.width = scaledWidth;
|
||||
thumbnailRect.size.height = scaledHeight;
|
||||
[sourceImage drawInRect:thumbnailRect
|
||||
fromRect:NSZeroRect
|
||||
operation:NSCompositingOperationSourceOver
|
||||
fraction:1.0];
|
||||
|
||||
[newImage unlockFocus];
|
||||
|
||||
[newImage setTemplate:[sourceImage isTemplate]];
|
||||
}
|
||||
}
|
||||
return [newImage autorelease];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSStatusBarButton (Swizzle)
|
||||
- (void)setImagePatched:(NSImage*)image {
|
||||
NSImage* img = image;
|
||||
|
||||
if (image != nil) {
|
||||
int thickness = [[NSStatusBar systemStatusBar] thickness];
|
||||
img = [NSImageScalingHelper imageByScaling:image size:NSMakeSize(thickness, thickness)];
|
||||
}
|
||||
|
||||
[self setImagePatched:img];
|
||||
}
|
||||
@end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue