5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-02 23:20:51 +08:00
wails/v2/internal/frontend/desktop/darwin/WailsContext.m

373 lines
11 KiB
Objective-C

//
// WailsContext.m
// test
//
// Created by Lea Anthony on 10/10/21.
//
#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>
#import "WailsContext.h"
#import "WindowDelegate.h"
#import "message.h"
@implementation WailsWindow
- (BOOL)canBecomeKeyWindow
{
return YES;
}
@end
@implementation WailsContext
- (void) SetSize:(int)width :(int)height {
if (self.shuttingDown) return;
NSRect frame = [self.mainWindow frame];
frame.origin.y += frame.size.height - height;
frame.size.width = width;
frame.size.height = height;
[self.mainWindow setFrame:frame display:TRUE animate:FALSE];
}
- (void) SetPosition:(int)x :(int)y {
if (self.shuttingDown) return;
NSScreen* screen = [self getCurrentScreen];
NSRect windowFrame = [self.mainWindow frame];
NSRect screenFrame = [screen visibleFrame];
windowFrame.origin.x += screenFrame.origin.x + (float)x;
windowFrame.origin.y += (screenFrame.origin.y + screenFrame.size.height) - windowFrame.size.height - (float)y;
[self.mainWindow setFrame:windowFrame display:TRUE animate:FALSE];
}
- (void) SetMinSize:(int)minWidth :(int)minHeight {
if (self.shuttingDown) return;
NSSize size = { minWidth, minHeight };
self.minSize = size;
[self.mainWindow setMinSize:size];
[self adjustWindowSize];
}
- (void) SetMaxSize:(int)maxWidth :(int)maxHeight {
if (self.shuttingDown) return;
NSSize size = { FLT_MAX, FLT_MAX };
size.width = maxWidth > 0 ? maxWidth : FLT_MAX;
size.height = maxHeight > 0 ? maxHeight : FLT_MAX;
self.maxSize = size;
[self.mainWindow setMinSize:size];
[self adjustWindowSize];
}
- (void) adjustWindowSize {
if (self.shuttingDown) return;
NSRect currentFrame = [self.mainWindow frame];
if ( currentFrame.size.width > self.maxSize.width ) currentFrame.size.width = self.maxSize.width;
if ( currentFrame.size.width < self.minSize.width ) currentFrame.size.width = self.minSize.width;
if ( currentFrame.size.height > self.maxSize.height ) currentFrame.size.height = self.maxSize.height;
if ( currentFrame.size.height < self.minSize.height ) currentFrame.size.height = self.minSize.height;
[self.mainWindow setFrame:currentFrame display:TRUE animate:FALSE];
}
- (void) dealloc {
[super dealloc];
[self.appdelegate release];
[self.mainWindow release];
[self.mouseEvent release];
[self.userContentController release];
[self.urlRequests release];
}
- (NSScreen*) getCurrentScreen {
NSScreen* screen = [self.mainWindow screen];
if( screen == NULL ) {
screen = [NSScreen mainScreen];
}
return screen;
}
- (void) SetTitle:(const char *)title {
NSString *_title = [NSString stringWithUTF8String:title];
[self.mainWindow setTitle:_title];
}
- (void) Center {
[self.mainWindow center];
}
- (void) CreateWindow:(int)width :(int)height :(bool)frameless :(bool)resizable :(bool)fullscreen :(bool)fullSizeContent :(bool)hideTitleBar :(bool)titlebarAppearsTransparent :(bool)hideTitle :(bool)useToolbar :(bool)hideToolbarSeparator :(bool)webviewIsTransparent :(bool)hideWindowOnClose :(const char *)appearance :(bool)windowIsTranslucent {
self.urlRequests = [NSMutableDictionary new];
NSWindowStyleMask styleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
if (frameless) {
styleMask = NSWindowStyleMaskBorderless;
} else {
if (resizable) {
styleMask |= NSWindowStyleMaskResizable;
}
}
if (fullscreen) {
styleMask |= NSWindowStyleMaskFullScreen;
}
if( fullSizeContent || frameless || titlebarAppearsTransparent ) {
styleMask |= NSWindowStyleMaskFullSizeContentView;
}
self.mainWindow = [[[WailsWindow alloc] initWithContentRect:NSMakeRect(0, 0, width, height)
styleMask:styleMask backing:NSBackingStoreBuffered defer:NO]
autorelease];
if (frameless) {
return;
}
if (useToolbar) {
NSLog(@"Using Toolbar");
id toolbar = [[NSToolbar alloc] initWithIdentifier:@"wails.toolbar"];
[toolbar autorelease];
[toolbar setShowsBaselineSeparator:!hideToolbarSeparator];
[self.mainWindow setToolbar:toolbar];
}
[self.mainWindow setTitleVisibility:hideTitle];
[self.mainWindow setTitlebarAppearsTransparent:titlebarAppearsTransparent];
[self.mainWindow canBecomeKeyWindow];
id contentView = [self.mainWindow contentView];
if (windowIsTranslucent) {
NSVisualEffectView *effectView = [NSVisualEffectView alloc];
NSRect bounds = [contentView bounds];
[effectView initWithFrame:bounds];
[effectView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[effectView setBlendingMode:NSVisualEffectBlendingModeBehindWindow];
[effectView setState:NSVisualEffectStateActive];
[contentView addSubview:effectView positioned:NSWindowBelow relativeTo:nil];
}
if (appearance != nil) {
NSString *name = [NSString stringWithUTF8String:appearance];
NSAppearance *nsAppearance = [NSAppearance appearanceNamed:name];
[self.mainWindow setAppearance:nsAppearance];
}
// Set up min/max
NSSize maxSize = { FLT_MAX, FLT_MAX };
self.maxSize = maxSize;
NSSize minSize = { 0, 0 };
self.minSize = minSize;
[self adjustWindowSize];
WindowDelegate *windowDelegate = [WindowDelegate new];
windowDelegate.hideOnClose = hideWindowOnClose;
[self.mainWindow setDelegate:windowDelegate];
// Webview stuff here!
WKWebViewConfiguration *config = [WKWebViewConfiguration new];
config.suppressesIncrementalRendering = true;
[config setURLSchemeHandler:self forURLScheme:@"wails"];
[config.preferences setValue:[NSNumber numberWithBool:true] forKey:@"developerExtrasEnabled"];
WKUserContentController* userContentController = [WKUserContentController new];
[userContentController addScriptMessageHandler:self name:@"external"];
config.userContentController = userContentController;
self.userContentController = userContentController;
if (self.debug) {
[config.preferences setValue:@YES forKey:@"developerExtrasEnabled"];
} else {
// Disable default context menus
WKUserScript *initScript = [WKUserScript new];
[initScript initWithSource:@"window.wails.flags.disableWailsDefaultContextMenu = true;"
injectionTime:WKUserScriptInjectionTimeAtDocumentEnd
forMainFrameOnly:false];
[userContentController addUserScript:initScript];
}
self.webview = [WKWebView alloc];
CGRect init = { 0,0,0,0 };
[self.webview initWithFrame:init configuration:config];
[contentView addSubview:self.webview];
[self.webview setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
CGRect contentViewBounds = [contentView bounds];
[self.webview setFrame:contentViewBounds];
if (webviewIsTransparent) {
[self.webview setValue:[NSNumber numberWithBool:!webviewIsTransparent] forKey:@"drawsBackground"];
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:FALSE forKey:@"NSAutomaticQuoteSubstitutionEnabled"];
// Mouse monitors
[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskLeftMouseDown handler:^NSEvent * _Nullable(NSEvent * _Nonnull event) {
id window = [event window];
if (window == self.mainWindow) {
self.mouseEvent = event;
}
return event;
}];
[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskLeftMouseUp handler:^NSEvent * _Nullable(NSEvent * _Nonnull event) {
id window = [event window];
if (window == self.mainWindow) {
self.mouseEvent = nil;
[self ShowMouse];
}
return event;
}];
}
- (void) loadRequest :(NSString*)url {
NSURL *wkUrl = [NSURL URLWithString:url];
NSURLRequest *wkRequest = [NSURLRequest requestWithURL:wkUrl];
[self.webview loadRequest:wkRequest];
}
- (void) SetRGBA:(int)r :(int)g :(int)b :(int)a {
float red = r/255;
float green = g/255;
float blue = b/255;
float alpha = a/255;
id colour = [NSColor colorWithCalibratedRed:red green:green blue:blue alpha:alpha ];
[self.mainWindow setBackgroundColor:colour];
}
- (void) HideMouse {
[NSCursor hide];
}
- (void) ShowMouse {
[NSCursor unhide];
}
- (bool) isFullScreen {
long mask = [self.mainWindow styleMask];
return (mask & NSWindowStyleMaskFullScreen) == NSWindowStyleMaskFullScreen;
}
// Fullscreen sets the main window to be fullscreen
- (void) Fullscreen {
if( ! [self isFullScreen] ) {
[self.mainWindow toggleFullScreen:nil];
}
}
// UnFullscreen resets the main window after a fullscreen
- (void) UnFullscreen {
if( [self isFullScreen] ) {
[self.mainWindow toggleFullScreen:nil];
}
}
- (void) Minimise {
[self.mainWindow miniaturize:nil];
}
- (void) UnMinimise {
[self.mainWindow deminiaturize:nil];
}
- (void) Hide {
[self.mainWindow orderOut:nil];
}
- (void) Show {
[self.mainWindow makeKeyAndOrderFront:nil];
[NSApp activateIgnoringOtherApps:YES];
}
- (void) Maximise {
if (! self.maximised) {
[self.mainWindow zoom:nil];
}
}
- (void) UnMaximise {
if (self.maximised) {
[self.mainWindow zoom:nil];
}
}
- (void) ExecJS:(const char*)script {
NSString *nsscript = [NSString stringWithUTF8String:script];
[self.webview evaluateJavaScript:nsscript completionHandler:nil];
}
- (void) processURLResponse:(NSString *)url :(NSString *)contentType :(NSData *)data {
id<WKURLSchemeTask> urlSchemeTask = self.urlRequests[url];
NSURL *nsurl = [NSURL URLWithString:url];
NSHTTPURLResponse *response = [NSHTTPURLResponse new];
NSMutableDictionary *headerFields = [NSMutableDictionary new];
headerFields[@"content-type"] = contentType;
[response initWithURL:nsurl statusCode:200 HTTPVersion:@"HTTP/1.1" headerFields:headerFields];
[urlSchemeTask didReceiveResponse:response];
[urlSchemeTask didReceiveData:data];
[urlSchemeTask didFinish];
[self.urlRequests removeObjectForKey:url];
}
- (void)webView:(nonnull WKWebView *)webView startURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask {
// Do something
self.urlRequests[urlSchemeTask.request.URL.absoluteString] = urlSchemeTask;
processURLRequest(self, [urlSchemeTask.request.URL.absoluteString UTF8String]);
}
- (void)webView:(nonnull WKWebView *)webView stopURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask {
}
- (void)userContentController:(nonnull WKUserContentController *)userContentController didReceiveScriptMessage:(nonnull WKScriptMessage *)message {
NSString *m = message.body;
// Check for drag
if ( [m isEqualToString:@"drag"] ) {
if( ! [self isFullScreen] ) {
if( self.mouseEvent != nil ) {
[self HideMouse];
ON_MAIN_THREAD(
[self.mainWindow performWindowDragWithEvent:self.mouseEvent];
);
}
return;
}
}
const char *_m = [m UTF8String];
processMessage(_m);
}
@end