Skip to content

Commit

Permalink
delegates
Browse files Browse the repository at this point in the history
  • Loading branch information
bung87 committed Oct 2, 2024
1 parent 8ae4d59 commit da31beb
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 32 deletions.
14 changes: 9 additions & 5 deletions src/crowngui/platforms/macos/app_delegate.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@ import darwin / [app_kit, foundation, objc/runtime]
import ../../types
import ./bundle

proc applicationOpenFile(self: ID; cmd: SEL; sender: NSApplication; openFile: NSString): Bool {.cdecl.} =
type MyAppDelegate* = ptr object of NSObject

proc setDelegate*(s: NSApplication, d: NSObject) {.objc: "setDelegate:".}

proc applicationOpenFile(self: MyAppDelegate; cmd: SEL; sender: NSApplication; openFile: NSString): Bool {.cdecl.} =
let path = cast[cstring](objc_msgSend(cast[ID](openFile), $$"UTF8String"))
var cls = self.getClass()
var ivar = cls.getIvar("webview")
var wv = cast[Webview](self.getIvar(ivar))
if wv.onOpenFile != nil:
return cast[Bool](wv.onOpenFile(wv, $path))

proc applicationShouldTerminateAfterLastWindowClosed(self: ID; cmd: SEL; notification: ID): bool {.cdecl.} =
proc applicationShouldTerminateAfterLastWindowClosed(self: MyAppDelegate; cmd: SEL; notification: ID): bool {.cdecl.} =
# return true, so will not stay in dock and wait for reactivation
return true

# applicationWillFinishLaunching: -> application:openFile: -> applicationDidFinishLaunching:
proc applicationWillFinishLaunching(self: ID; cmd: SEL; notification: ID): void {.cdecl.} =
proc applicationWillFinishLaunching(self: MyAppDelegate; cmd: SEL; notification: ID): void {.cdecl.} =
when not defined(release):
echo "applicationWillFinishLaunching"

Expand All @@ -29,7 +33,7 @@ proc on_application_did_finish_launching(delegate: ID; app: ID) {.objcr.}=
[app activateIgnoringOtherApps: YES]
# set_up_window()

proc applicationDidFinishLaunching(self: ID; cmd: SEL; notification: ID): void {.cdecl.} =
proc applicationDidFinishLaunching(self: MyAppDelegate; cmd: SEL; notification: ID): void {.cdecl.} =
when not defined(release):
echo "applicationDidFinishLaunching"
# var w = getAssociatedObject(self, cast[pointer]($$"webview"))
Expand All @@ -39,7 +43,7 @@ proc applicationDidFinishLaunching(self: ID; cmd: SEL; notification: ID): void {
let app = [notification $$"object"]
on_application_did_finish_launching(self, app)

proc applicationWillBecomeActive(self: ID; cmd: SEL; notification: ID): void {.cdecl.} =
proc applicationWillBecomeActive(self: MyAppDelegate; cmd: SEL; notification: ID): void {.cdecl.} =
# close button pressed, stay in dock. then press from dock to activate app.
when not defined(release):
echo "applicationWillBecomeActive"
Expand Down
8 changes: 6 additions & 2 deletions src/crowngui/platforms/macos/navigation_delegate.nim
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import objc_runtime
import darwin / [objc/blocks]
import darwin / [objc/blocks, web_kit]

const WKNavigationActionPolicyDownload = 2
const WKNavigationResponsePolicyAllow = 1

type MyWKNavigationDelegate* = ptr object of NSObject

proc setNavigationDelegate*(s: WKWebview, d: NSObject) {.objc: "setNavigationDelegate:".}

proc make_nav_policy_decision(self: Id; cmd: SEL; webView: Id; response: Id;
decisionHandler: Block[proc (): void]) =
objcr:
Expand All @@ -14,7 +18,7 @@ proc make_nav_policy_decision(self: Id; cmd: SEL; webView: Id; response: Id;

proc registerWKNavigationDelegate*(): ObjcClass =
result = allocateClassPair(
getClass("NSObject"), "PrivWKNavigationDelegate", 0)
getClass("NSObject"), "MyWKNavigationDelegate", 0)
discard addProtocol(result, getProtocol("WKNavigationDelegate"))
discard addMethod(
result,
Expand Down
3 changes: 2 additions & 1 deletion src/crowngui/platforms/macos/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import darwin/app_kit/nswindow
import darwin/web_kit/wkwebview

type
MyNSWindowDelegate* = ptr object of NSObject
WebviewPrivObj* = object
pool*: ID
window*: NSWindow
webview*: WKWebView
windowDelegate*: ID
windowDelegate*: MyNSWindowDelegate
8 changes: 6 additions & 2 deletions src/crowngui/platforms/macos/ui_delegate.nim
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import objc_runtime
import darwin / [app_kit, foundation, objc/runtime]
import darwin / [app_kit, web_kit, foundation, objc/runtime]
import ./internal_dialogs

type MyUIDelegate* = ptr object of NSObject

proc setUIDelegate*(s: WKWebview, d: NSObject) {.objc: "setUIDelegate:".}

proc registerUIDelegate*(): ObjcClass =
result = allocateClassPair(getClass("NSObject"), "PrivWKUIDelegate", 0)
result = allocateClassPair(getClass("NSObject"), "MyWKUIDelegate", 0)
discard addProtocol(result, getProtocol("WKUIDelegate"))
discard addMethod(result,
$$"webView:runOpenPanelWithParameters:initiatedByFrame:completionHandler:",
Expand Down
22 changes: 12 additions & 10 deletions src/crowngui/platforms/macos/webview.nim
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ proc webview_init*(w: Webview): cint {.objcr.} =
# [processPool "_setDownloadDelegate": downloadDelegate]
# [config setProcessPool: processPool]

var PrivNSWindowDelegate = registerWindowDelegate()
w.priv.windowDelegate = [PrivNSWindowDelegate new]
var MyNSWindowDelegateClass = registerWindowDelegate()
w.priv.windowDelegate = cast[MyNSWindowDelegate](createInstance(MyNSWindowDelegateClass, 0))
setAssociatedObject(w.priv.windowDelegate, cast[pointer]($$"webview"), (Id)(w),
OBJC_ASSOCIATION_ASSIGN)

Expand All @@ -89,20 +89,22 @@ proc webview_init*(w: Webview): cint {.objcr.} =
w.priv.window.initWithContentRect(frameRect, cast[NSWindowStyleMask](style), NSBackingStoreBuffered, NO)
[w.priv.window autorelease]
w.priv.window.setTitle(@($w.title))
let send = cast[proc(self:ID; sel: SEL; t: ID){.cdecl,gcsafe.}](objc_msgSend)
send(w.priv.window, $$"setDelegate:", w.priv.windowDelegate)

w.priv.window.setDelegate(w.priv.windowDelegate)
w.priv.window.center()
var PrivWKUIDelegate = registerUIDelegate()
var uiDel = [PrivWKUIDelegate new]
var MyWKUIDelegateClass = registerUIDelegate()
var uiDel = cast[MyUIDelegate](createInstance(MyWKUIDelegateClass, 0))

var PrivWKNavigationDelegate = registerWKNavigationDelegate()
var navDel = [PrivWKNavigationDelegate new]
var MyWKNavigationDelegateClass = registerWKNavigationDelegate()
var navDel = cast[MyWKNavigationDelegate](createInstance(MyWKNavigationDelegateClass, 0))

w.priv.webview = WKWebView.alloc()

discard initWithFrameAndConfiguration(w.priv.webview, frameRect, config)
send(w.priv.webview, $$"setUIDelegate:", uiDel)
send(w.priv.webview, $$"setNavigationDelegate:", navDel)

w.priv.webview.setUIDelegate(uiDel)
w.priv.webview.setNavigationDelegate(navDel)

let url = $(w.url)
case w.entryType
of EntryType.html:
Expand Down
3 changes: 3 additions & 0 deletions src/crowngui/platforms/macos/window_delegate.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import objc_runtime
import darwin / [app_kit, objc/runtime]
import ../../types


proc setDelegate*(s: NSWindow, d: NSObject) {.objc: "setDelegate:".}

proc webview_window_will_close(self: Id; cmd: SEL; notification: Id) =
var w = getAssociatedObject(self, cast[pointer]($$"webview"))
var wv = cast[Webview](w)
Expand Down
6 changes: 5 additions & 1 deletion src/crowngui/platforms/macos/windowcontroller.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
import objc_runtime
import darwin / [app_kit, foundation, objc/runtime]

type MyWindowController* = ptr object of NSObject

proc setDelegate*(s: NSWindow, d: NSObject) {.objc: "setDelegate:".}

when false:
proc awakeFromNib(self: ID; cmd: SEL; ): void {.cdecl.} =
objcr:
Expand All @@ -22,7 +26,7 @@ when false:
[self registerForDraggedTypes: tid]
return self

proc draggingEntered(self: ID; cmd: SEL; sender: NSDraggingInfo): NSDragOperation {.cdecl.} =
proc draggingEntered(self: MyWindowController; cmd: SEL; sender: NSDraggingInfo): NSDragOperation {.cdecl.} =
return NSDragOperationCopy

proc registerWindowController*(): ObjcClass =
Expand Down
18 changes: 7 additions & 11 deletions src/crowngui/webview.nim
Original file line number Diff line number Diff line change
Expand Up @@ -214,19 +214,15 @@ proc newWebView*(path: static[string] = ""; entryType:static[EntryType]; title =
entryType1 = EntryType.html
var webview = webView(title, entry, entryType1, width, height, resizable, debug, callback)
when defined(macosx):
let MyAppDelegate = registerAppDelegate()
let WindowController = registerWindowController()
let send1 = cast[proc(self: NSWindow; sel: SEL; c: ID){.cdecl,gcsafe.}](objc_msgSend)
let send2 = cast[proc(self: NSApplication; sel: SEL; c: ID){.cdecl,gcsafe.}](objc_msgSend)
let MyAppDelegateClass = registerAppDelegate()
let MyWindowControllerClass = registerWindowController()

objcr:
var appDel = [MyAppDelegate new]
var windowController = [WindowController new]
# [webview.priv.window setDelegate: windowController]
send1(webview.priv.window, $$"setDelegate:", windowController)
# [app setDelegate: appDel]
send2(cast[NSApplication](NSApp), $$"setDelegate:", appDel)
let ivar: Ivar = getIvar(MyAppDelegate, "webview")
var appDel = cast[MyAppDelegate](createInstance(MyAppDelegateClass, 0))
var windowController = cast[MyWindowController](createInstance(MyWindowControllerClass, 0)) # [MyWindowController new]
webview.priv.window.setDelegate(windowController)
cast[NSApplication](NSApp).setDelegate(appDel)
let ivar: Ivar = getIvar(MyAppDelegateClass, "webview")
setIvar(appDel, ivar, cast[ID](webview))
createMenu()

Expand Down

0 comments on commit da31beb

Please sign in to comment.