Cocoa - how to block popup menu for WebGadget

Mac OSX specific forum
flashbob
User
User
Posts: 92
Joined: Sat May 11, 2024 4:04 pm

Cocoa - how to block popup menu for WebGadget

Post by flashbob »

Any way to block the default popup in WebGadget via cocoa ?
I would like to display my own popup menu when I right click.
Thanks in advance
r-i-v-e-r
User
User
Posts: 20
Joined: Thu May 09, 2024 5:18 pm

Re: Cocoa - how to block popup menu for WebGadget

Post by r-i-v-e-r »

It'd probably be easiest to handle the contextmenu event on the JS side instead, that way you avoid having to write more platform-specific code. It'd also be easier to get information on the DOM node target this way.

Still, if you want to go the Cocoa route, you can respond to the WebUIDelegate's webView:contextMenuItemsForElement:defaultMenuItems:, for example:

Code: Select all

EnableExplicit

;; Helpers
;; =======================================================

Procedure.s pbStringFromNSString(*string)
  ProcedureReturn PeekS(CocoaMessage(0, *string, "UTF8String"), -1, #PB_UTF8)
EndProcedure

Procedure debugNSDictionary(*dict)
  Protected count = CocoaMessage(0, *dict, "count")
  Protected Dim values(count)
  Protected Dim keys(count)
  CocoaMessage(0, *dict, "getObjects:", @values(), "andKeys:", @keys(), "count:", count)
  Define x 
  For x = 0 To count - 1
    Debug "  " + pbStringFromNSString(keys(x)) + " -> "  + values(x)
  Next x
EndProcedure

;; Setup a new WebUIDelegate class.
;; =======================================================

;{ class RVR_WebView_UIDelegate begin
ProcedureC delegate_webView__contextMenuItemsForElement__defaultMenuItems(*self, *cmd, *webView, *element, *defaultMenuItems)
  Debug "Request for context-menu display:"
  debugNSDictionary(*element)
  Debug ""
EndProcedure

Define clsWebViewDelegate = objc_allocateClassPair_(objc_getClass_("NSObject"), "RVR_WebView_UIDelegate", 0)
class_addProtocol_(clsWebViewDelegate, objc_getProtocol_("WebUIDelegate"))
class_addMethod_(clsWebViewDelegate, sel_registerName_("webView:contextMenuItemsForElement:defaultMenuItems:"), @delegate_webView__contextMenuItemsForElement__defaultMenuItems(), "@@:@@@")
objc_registerClassPair_(clsWebViewDelegate)
;} end class RVR_WebView_UIDelegate

;; Main.
;; =======================================================

Define wnd = OpenWindow(#PB_Any, 0, 0, 600, 400, "WebGadget menu override", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Define webGad = WebGadget(#PB_Any, 0, 0, 600, 400, "")
SetGadgetItemText(webGad, #PB_Web_HtmlCode, "<html><body>Right click me.</body></html>")

CocoaMessage(0, GadgetID(webGad), "setUIDelegate:", CocoaMessage(0, clsWebViewDelegate, "alloc"))

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
From the delegate_webView__contextMenuItemsForElement__defaultMenuItems() procedure, you can extract element info from the *element NSDictionary, and accordingly return an NSArray of menu items or display a popup menu yourself with DisplayPopupMenu(), etc.

For completion's sake, here's an example of the cross-platform, JS approach:

Code: Select all

EnableExplicit

;; Helpers.
;; =======================================================

Procedure webViewOnContextMenu(paramsJson.s)
  Debug "Handle context menu: " + paramsJson
EndProcedure

;; Main.
;; =======================================================

Define html.s = "<html>" +
                "<head><script>" +
                "document.oncontextmenu = function(ev) { ev.preventDefault(); handleContextMenu(); }" +
                "</script></head>" +
                "<body>Right click anywhere.</body>" +
                "</html>"

Define wnd = OpenWindow(#PB_Any, 0, 0, 600, 400, "WebGadget menu override", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Define webGad = WebViewGadget(#PB_Any, 0, 0, 600, 400)
SetGadgetItemText(webGad, #PB_WebView_HtmlCode, html)
BindWebViewCallback(webGad, "handleContextMenu", @webViewOnContextMenu())

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
I've used the WebViewGadget (which should be preferred where possible) for simplicity in bridging JS<->PB, but this is adaptable to the IE WebGadget as well by interfacing with the underlying IWebBrowser2.
User avatar
Piero
Addict
Addict
Posts: 923
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: Cocoa - how to block popup menu for WebGadget

Post by Piero »

It's great to have "newcomers" like you, r-i-v-e-r, welcome!
I had posted a funny "ol' man r-i-v-e-r" thing, but the wise forum admins probably thought it was somewhat offensive :?
Post Reply