some context menu in webview

This commit is contained in:
Adam D. Ruppe 2023-11-01 10:09:04 -04:00
parent 2aa06d0568
commit 8d73ec2603
2 changed files with 149 additions and 4 deletions

8
core.d
View File

@ -6887,7 +6887,7 @@ If you are not sure if Cocoa thinks your application is multithreaded or not, yo
} }
extern class NSNotification : NSObject { extern class NSNotification : NSObject {
@property NSid object() @selector("object");
} }
enum NSApplicationActivationPolicy : ptrdiff_t { enum NSApplicationActivationPolicy : ptrdiff_t {
@ -7007,6 +7007,8 @@ If you are not sure if Cocoa thinks your application is multithreaded or not, yo
void windowDidResize(NSNotification notification) @selector("windowDidResize:"); void windowDidResize(NSNotification notification) @selector("windowDidResize:");
NSSize windowWillResize(NSWindow sender, NSSize frameSize) @selector("windowWillResize:toSize:"); NSSize windowWillResize(NSWindow sender, NSSize frameSize) @selector("windowWillResize:toSize:");
void windowWillClose(NSNotification notification) @selector("windowWillClose:");
} }
extern class NSView : NSResponder { extern class NSView : NSResponder {
@ -7032,6 +7034,10 @@ If you are not sure if Cocoa thinks your application is multithreaded or not, yo
@property NSRect frame(NSRect rect) @selector("setFrame:"); @property NSRect frame(NSRect rect) @selector("setFrame:");
void setFrameSize(NSSize newSize) @selector("setFrameSize:"); void setFrameSize(NSSize newSize) @selector("setFrameSize:");
void setFrameOrigin(NSPoint newOrigin) @selector("setFrameOrigin:");
void addSubview(NSView what) @selector("addSubview:");
void removeFromSuperview() @selector("removeFromSuperview:");
} }
extern class NSFont : NSObject { extern class NSFont : NSObject {

View File

@ -120,7 +120,7 @@ class WebViewWidget_WV2 : WebViewWidgetBase {
private bool initialized; private bool initialized;
this(string url, void delegate(scope OpenNewWindowParams) openNewWindow, BrowserSettings settings, Widget parent) { this(string url, void delegate(scope OpenNewWindowParams) openNewWindow, BrowserSettings settings, Widget parent) {
// FIXME: openNewWindow // FIXME: openNewWindow and openUrlInNewWindow
super(parent); super(parent);
// that ctor sets containerWindow // that ctor sets containerWindow
@ -474,6 +474,11 @@ class WebViewWidget_CEF : WebViewWidgetBase {
}); });
} }
~this() {
import core.stdc.stdio;
printf("GC'd %p\n", cast(void*) this);
}
private MiniguiCefClient client; private MiniguiCefClient client;
override void registerMovementAdditionalWork() { override void registerMovementAdditionalWork() {
@ -630,7 +635,7 @@ version(cef) {
if(auto wvp = wh in WebViewWidget.browserMapping) { if(auto wvp = wh in WebViewWidget.browserMapping) {
dg(*wvp); dg(*wvp);
} else { } else {
//writeln("not found ", wh, WebViewWidget.browserMapping); writeln("not found ", wh, WebViewWidget.browserMapping);
} }
}); });
} }
@ -1030,6 +1035,118 @@ version(cef) {
} }
} }
class MiniguiContextMenuHandler : CEF!cef_context_menu_handler_t {
private MiniguiCefClient client;
this(MiniguiCefClient client) {
this.client = client;
}
override void on_before_context_menu(RC!(cef_browser_t) browser, RC!(cef_frame_t) frame, RC!(cef_context_menu_params_t) params, RC!(cef_menu_model_t) model) nothrow {
// FIXME: should i customize these? it is kinda specific to my browser
int itemNo;
void addItem(string label, int commandNo) {
auto lbl = cef_string_t(label);
model.insert_item_at(/* index */ itemNo, /* command id */ cef_menu_id_t.MENU_ID_USER_FIRST + commandNo, &lbl);
itemNo++;
}
void addSeparator() {
model.insert_separator_at(itemNo);
itemNo++;
}
auto flags = params.get_type_flags();
if(flags & cef_context_menu_type_flags_t.CM_TYPEFLAG_LINK) {
// cef_string_userfree_t linkUrl = params.get_unfiltered_link_url();
// toGCAndFree
addItem("Open link in new window", 1);
addItem("Copy link URL", 2);
// FIXME: open in other browsers
addSeparator();
}
if(flags & cef_context_menu_type_flags_t.CM_TYPEFLAG_MEDIA) {
// cef_string_userfree_t linkUrl = params.get_source_url();
// toGCAndFree
addItem("Open media in new window", 3);
addItem("Copy source URL", 4);
addItem("Download media", 5);
addSeparator();
}
// get_page_url
// get_title_text
// has_image_contents ???
// get_source_url
// get_xcoord and get_ycoord
// get_selection_text
}
override int run_context_menu(RC!(cef_browser_t), RC!(cef_frame_t), RC!(cef_context_menu_params_t), RC!(cef_menu_model_t), RC!(cef_run_context_menu_callback_t)) nothrow {
// could do a custom display here if i want but i think it is good enough as it is
return 0;
}
override int on_context_menu_command(RC!(cef_browser_t) browser, RC!(cef_frame_t) frame, RC!(cef_context_menu_params_t) params, int commandId, cef_event_flags_t flags) nothrow {
switch(commandId) {
case cef_menu_id_t.MENU_ID_USER_FIRST + 1: // open link in new window
auto what = params.get_unfiltered_link_url().toGCAndFree();
browser.runOnWebView((widget) {
auto event = new NewWindowRequestedEvent(what, widget);
event.dispatch();
});
return 1;
case cef_menu_id_t.MENU_ID_USER_FIRST + 2: // copy link url
auto what = params.get_link_url().toGCAndFree();
browser.runOnWebView((widget) {
auto event = new CopyRequestedEvent(what, widget);
event.dispatch();
});
return 1;
case cef_menu_id_t.MENU_ID_USER_FIRST + 3: // open media in new window
auto what = params.get_source_url().toGCAndFree();
browser.runOnWebView((widget) {
auto event = new NewWindowRequestedEvent(what, widget);
event.dispatch();
});
return 1;
case cef_menu_id_t.MENU_ID_USER_FIRST + 4: // copy source url
auto what = params.get_source_url().toGCAndFree();
browser.runOnWebView((widget) {
auto event = new CopyRequestedEvent(what, widget);
event.dispatch();
});
return 1;
case cef_menu_id_t.MENU_ID_USER_FIRST + 5: // download media
auto str = cef_string_t(params.get_source_url().toGCAndFree());
browser.get_host().start_download(&str);
return 1;
default:
return 0;
}
}
override void on_context_menu_dismissed(RC!(cef_browser_t), RC!(cef_frame_t)) nothrow {
// to close the custom display
}
override int run_quick_menu(RC!(cef_browser_t), RC!(cef_frame_t), const(cef_point_t)*, const(cef_size_t)*, cef_quick_menu_edit_state_flags_t, RC!(cef_run_quick_menu_callback_t)) nothrow {
return 0;
}
override int on_quick_menu_command(RC!(cef_browser_t), RC!(cef_frame_t), int, cef_event_flags_t) nothrow {
return 0;
}
override void on_quick_menu_dismissed(RC!(cef_browser_t), RC!(cef_frame_t)) nothrow {
}
}
class MiniguiFocusHandler : CEF!cef_focus_handler_t { class MiniguiFocusHandler : CEF!cef_focus_handler_t {
override void on_take_focus(RC!(cef_browser_t) browser, int next) nothrow { override void on_take_focus(RC!(cef_browser_t) browser, int next) nothrow {
browser.runOnWebView(delegate(wv) { browser.runOnWebView(delegate(wv) {
@ -1083,6 +1200,7 @@ version(cef) {
MiniguiKeyboardHandler keyboardHandler; MiniguiKeyboardHandler keyboardHandler;
MiniguiFocusHandler focusHandler; MiniguiFocusHandler focusHandler;
MiniguiRequestHandler requestHandler; MiniguiRequestHandler requestHandler;
MiniguiContextMenuHandler contextMenuHandler;
this(void delegate(scope OpenNewWindowParams) openNewWindow) { this(void delegate(scope OpenNewWindowParams) openNewWindow) {
this.openNewWindow = openNewWindow; this.openNewWindow = openNewWindow;
lsh = new MiniguiCefLifeSpanHandler(this); lsh = new MiniguiCefLifeSpanHandler(this);
@ -1093,13 +1211,14 @@ version(cef) {
keyboardHandler = new MiniguiKeyboardHandler(); keyboardHandler = new MiniguiKeyboardHandler();
focusHandler = new MiniguiFocusHandler(); focusHandler = new MiniguiFocusHandler();
requestHandler = new MiniguiRequestHandler(); requestHandler = new MiniguiRequestHandler();
contextMenuHandler = new MiniguiContextMenuHandler(this);
} }
override cef_audio_handler_t* get_audio_handler() { override cef_audio_handler_t* get_audio_handler() {
return null; return null;
} }
override cef_context_menu_handler_t* get_context_menu_handler() { override cef_context_menu_handler_t* get_context_menu_handler() {
return null; return contextMenuHandler.returnable;
} }
override cef_dialog_handler_t* get_dialog_handler() { override cef_dialog_handler_t* get_dialog_handler() {
return dialogHandler.returnable; return dialogHandler.returnable;
@ -1171,6 +1290,26 @@ class BrowserClosedEvent : Event {
override bool cancelable() const { return false; } override bool cancelable() const { return false; }
} }
class CopyRequestedEvent : Event {
enum EventString = "browsercopyrequested";
string what;
this(string what, Widget target) { this.what = what; super(EventString, target); }
override bool cancelable() const { return false; }
}
class NewWindowRequestedEvent : Event {
enum EventString = "browserwindowrequested";
string url;
this(string url, Widget target) { this.url = url; super(EventString, target); }
override bool cancelable() const { return false; }
}
/+ /+
pragma(mangle, "_ZN12CefWindowX115FocusEv") pragma(mangle, "_ZN12CefWindowX115FocusEv")
//pragma(mangle, "_ZN3x116XProto13SetInputFocusERKNS_20SetInputFocusRequestE") //pragma(mangle, "_ZN3x116XProto13SetInputFocusERKNS_20SetInputFocusRequestE")