-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmac.mm
158 lines (142 loc) · 5.71 KB
/
mac.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Copyright 2022-present Contributors to the jobman project.
// SPDX-License-Identifier: BSD-3-Clause
// https://github.com/mikaelsundell/jobman
#include "mac.h"
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#include <os/log.h>
#include <QGuiApplication>
#include <QScreen>
namespace mac
{
namespace utils {
QPointF toNativeCursor(int x, int y)
{
QScreen* screen = QGuiApplication::primaryScreen();
QPointF cursor = QPointF(x, y);
qreal reverse = screen->geometry().height() - cursor.y();
return QPointF(cursor.x(), reverse);
}
NSWindow* toNativeWindow(WId winId)
{
NSView *view = (NSView*)winId;
return [view window];
}
NSScreen* toNativeScreen(WId winId)
{
NSWindow *window = toNativeWindow(winId);
return [window screen];
}
struct ColorSyncProfile {
uint32_t screenNumber;
CFStringRef displayProfileUrl;
ColorSyncProfile() : screenNumber(0), displayProfileUrl(nullptr) {}
ColorSyncProfile(const ColorSyncProfile& other)
: screenNumber(other.screenNumber) {
displayProfileUrl = other.displayProfileUrl ? static_cast<CFStringRef>(CFRetain(other.displayProfileUrl)) : nullptr;
}
ColorSyncProfile& operator=(const ColorSyncProfile& other) {
if (this != &other) {
screenNumber = other.screenNumber;
if (displayProfileUrl) CFRelease(displayProfileUrl);
displayProfileUrl = other.displayProfileUrl ? static_cast<CFStringRef>(CFRetain(other.displayProfileUrl)) : nullptr;
}
return *this;
}
~ColorSyncProfile() {
if (displayProfileUrl) CFRelease(displayProfileUrl);
}
};
QMap<uint32_t, ColorSyncProfile> colorsynccache;
ColorSyncProfile grabColorSyncProfile(NSScreen* screen)
{
ColorSyncProfile colorSyncProfile;
NSDictionary* screenDescription = [screen deviceDescription];
NSNumber* screenID = [screenDescription objectForKey:@"NSScreenNumber"];
colorSyncProfile.screenNumber = [screenID unsignedIntValue];
ColorSyncProfileRef csProfileRef = ColorSyncProfileCreateWithDisplayID((CGDirectDisplayID)colorSyncProfile.screenNumber);
if (csProfileRef) {
CFURLRef iccURLRef = ColorSyncProfileGetURL(csProfileRef, NULL);
if (iccURLRef) {
colorSyncProfile.displayProfileUrl = CFURLCopyFileSystemPath(iccURLRef, kCFURLPOSIXPathStyle);
}
CFRelease(csProfileRef);
}
return colorSyncProfile;
}
ColorSyncProfile grabDisplayProfile(NSScreen* screen) {
NSDictionary* screenDescription = [screen deviceDescription];
CGDirectDisplayID displayId = [[screenDescription objectForKey:@"NSScreenNumber"] unsignedIntValue];
if (colorsynccache.contains(displayId)) {
return colorsynccache.value(displayId);
}
ColorSyncProfile colorSyncProfile = grabColorSyncProfile(screen);
colorsynccache.insert(displayId, colorSyncProfile);
return colorSyncProfile;
}
}
void setDarkAppearance()
{
// we force dark aque no matter appearance set in system settings
[NSApp setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameDarkAqua]];
}
IccProfile grabIccProfile(WId wid)
{
NSScreen* screen = utils::toNativeScreen(wid);
utils::ColorSyncProfile colorsyncProfile = utils::grabDisplayProfile(screen);
return IccProfile {
int(colorsyncProfile.screenNumber),
QString::fromCFString(colorsyncProfile.displayProfileUrl)
};
}
QString grabIccProfileUrl(WId wid)
{
return grabIccProfile(wid).displayProfileUrl;
}
QString resolveBookmark(const QString& bookmark)
{
if (bookmark.isEmpty()) {
return QString();
}
QByteArray bookmarkData = QByteArray::fromBase64(bookmark.toUtf8());
NSError* error = nil;
BOOL isstale = NO;
NSURL *url = [NSURL URLByResolvingBookmarkData:[NSData dataWithBytes:bookmarkData.data() length:bookmarkData.size()]
options:NSURLBookmarkResolutionWithSecurityScope
relativeToURL:nil
bookmarkDataIsStale:&isstale
error:&error];
if (url && !error) {
if ([url startAccessingSecurityScopedResource]) {
return QString::fromUtf8([[url path] UTF8String]);
} else {
QString();
}
} else {
QString();
}
return QString();
}
QString saveBookmark(const QString& bookmark)
{
if (bookmark.isEmpty()) {
return QString();
}
NSURL* url = [NSURL fileURLWithPath:[NSString stringWithUTF8String:bookmark.toUtf8().constData()]];
NSError* error = nil;
NSData* bookmarkData = [url bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
includingResourceValuesForKeys:nil
relativeToURL:nil
error:&error];
if (bookmarkData && !error) {
QByteArray bookmark((const char *)[bookmarkData bytes], [bookmarkData length]);
return QString::fromUtf8(bookmark.toBase64());
} else {
return QString();
}
}
void console(const QString& log)
{
NSLog(@"%@", log.toNSString());
}
}