Page 1 of 1

Cocoa - how to block popup menu for WebGadget

Posted: Wed May 15, 2024 2:17 pm
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

Re: Cocoa - how to block popup menu for WebGadget

Posted: Thu May 16, 2024 11:41 pm
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.

Re: Cocoa - how to block popup menu for WebGadget

Posted: Fri May 17, 2024 12:44 pm
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 :?