mirror of
https://github.com/taigrr/wails.git
synced 2026-04-14 10:50:53 -07:00
Trim windows version
This commit is contained in:
@@ -39,23 +39,6 @@ extern "C"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(WEBVIEW_GTK)
|
||||
#include <JavaScriptCore/JavaScript.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <webkit2/webkit2.h>
|
||||
|
||||
struct webview_priv
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *scroller;
|
||||
GtkWidget *webview;
|
||||
GtkWidget *inspector_window;
|
||||
GAsyncQueue *queue;
|
||||
int ready;
|
||||
int js_busy;
|
||||
int should_exit;
|
||||
};
|
||||
#elif defined(WEBVIEW_WINAPI)
|
||||
#define CINTERFACE
|
||||
#include <windows.h>
|
||||
|
||||
@@ -76,22 +59,6 @@ struct webview_priv
|
||||
DWORD saved_ex_style;
|
||||
RECT saved_rect;
|
||||
};
|
||||
#elif defined(WEBVIEW_COCOA)
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
#import <objc/runtime.h>
|
||||
|
||||
struct webview_priv
|
||||
{
|
||||
NSAutoreleasePool *pool;
|
||||
NSWindow *window;
|
||||
WebView *webview;
|
||||
id delegate;
|
||||
int should_exit;
|
||||
};
|
||||
#else
|
||||
#error "Define one of: WEBVIEW_GTK, WEBVIEW_COCOA or WEBVIEW_WINAPI"
|
||||
#endif
|
||||
|
||||
struct webview;
|
||||
|
||||
@@ -182,9 +149,6 @@ struct webview_priv
|
||||
WEBVIEW_API void webview_debug(const char *format, ...);
|
||||
WEBVIEW_API void webview_print_log(const char *s);
|
||||
|
||||
#ifdef WEBVIEW_IMPLEMENTATION
|
||||
#undef WEBVIEW_IMPLEMENTATION
|
||||
|
||||
WEBVIEW_API int webview(const char *title, const char *url, int width,
|
||||
int height, int resizable)
|
||||
{
|
||||
@@ -264,301 +228,6 @@ struct webview_priv
|
||||
return r;
|
||||
}
|
||||
|
||||
#if defined(WEBVIEW_GTK)
|
||||
static void external_message_received_cb(WebKitUserContentManager *m,
|
||||
WebKitJavascriptResult *r,
|
||||
gpointer arg)
|
||||
{
|
||||
(void)m;
|
||||
struct webview *w = (struct webview *)arg;
|
||||
if (w->external_invoke_cb == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
JSGlobalContextRef context = webkit_javascript_result_get_global_context(r);
|
||||
JSValueRef value = webkit_javascript_result_get_value(r);
|
||||
JSStringRef js = JSValueToStringCopy(context, value, NULL);
|
||||
size_t n = JSStringGetMaximumUTF8CStringSize(js);
|
||||
char *s = g_new(char, n);
|
||||
JSStringGetUTF8CString(js, s, n);
|
||||
w->external_invoke_cb(w, s);
|
||||
JSStringRelease(js);
|
||||
g_free(s);
|
||||
}
|
||||
|
||||
static void webview_load_changed_cb(WebKitWebView *webview,
|
||||
WebKitLoadEvent event, gpointer arg)
|
||||
{
|
||||
(void)webview;
|
||||
struct webview *w = (struct webview *)arg;
|
||||
if (event == WEBKIT_LOAD_FINISHED)
|
||||
{
|
||||
w->priv.ready = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void webview_destroy_cb(GtkWidget *widget, gpointer arg)
|
||||
{
|
||||
(void)widget;
|
||||
struct webview *w = (struct webview *)arg;
|
||||
webview_terminate(w);
|
||||
}
|
||||
|
||||
static gboolean webview_context_menu_cb(WebKitWebView *webview,
|
||||
GtkWidget *default_menu,
|
||||
WebKitHitTestResult *hit_test_result,
|
||||
gboolean triggered_with_keyboard,
|
||||
gpointer userdata)
|
||||
{
|
||||
(void)webview;
|
||||
(void)default_menu;
|
||||
(void)hit_test_result;
|
||||
(void)triggered_with_keyboard;
|
||||
(void)userdata;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
WEBVIEW_API int webview_init(struct webview *w)
|
||||
{
|
||||
if (gtk_init_check(0, NULL) == FALSE)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
w->priv.ready = 0;
|
||||
w->priv.should_exit = 0;
|
||||
w->priv.queue = g_async_queue_new();
|
||||
w->priv.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title(GTK_WINDOW(w->priv.window), w->title);
|
||||
|
||||
if (w->resizable)
|
||||
{
|
||||
gtk_window_set_default_size(GTK_WINDOW(w->priv.window), w->width,
|
||||
w->height);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_set_size_request(w->priv.window, w->width, w->height);
|
||||
}
|
||||
gtk_window_set_resizable(GTK_WINDOW(w->priv.window), !!w->resizable);
|
||||
gtk_window_set_position(GTK_WINDOW(w->priv.window), GTK_WIN_POS_CENTER);
|
||||
|
||||
w->priv.scroller = gtk_scrolled_window_new(NULL, NULL);
|
||||
gtk_container_add(GTK_CONTAINER(w->priv.window), w->priv.scroller);
|
||||
|
||||
WebKitUserContentManager *m = webkit_user_content_manager_new();
|
||||
webkit_user_content_manager_register_script_message_handler(m, "external");
|
||||
g_signal_connect(m, "script-message-received::external",
|
||||
G_CALLBACK(external_message_received_cb), w);
|
||||
|
||||
w->priv.webview = webkit_web_view_new_with_user_content_manager(m);
|
||||
webkit_web_view_load_uri(WEBKIT_WEB_VIEW(w->priv.webview),
|
||||
webview_check_url(w->url));
|
||||
g_signal_connect(G_OBJECT(w->priv.webview), "load-changed",
|
||||
G_CALLBACK(webview_load_changed_cb), w);
|
||||
gtk_container_add(GTK_CONTAINER(w->priv.scroller), w->priv.webview);
|
||||
|
||||
if (w->debug)
|
||||
{
|
||||
WebKitSettings *settings =
|
||||
webkit_web_view_get_settings(WEBKIT_WEB_VIEW(w->priv.webview));
|
||||
webkit_settings_set_enable_write_console_messages_to_stdout(settings, true);
|
||||
webkit_settings_set_enable_developer_extras(settings, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_signal_connect(G_OBJECT(w->priv.webview), "context-menu",
|
||||
G_CALLBACK(webview_context_menu_cb), w);
|
||||
}
|
||||
|
||||
gtk_widget_show_all(w->priv.window);
|
||||
|
||||
webkit_web_view_run_javascript(
|
||||
WEBKIT_WEB_VIEW(w->priv.webview),
|
||||
"window.external={invoke:function(x){"
|
||||
"window.webkit.messageHandlers.external.postMessage(x);}}",
|
||||
NULL, NULL, NULL);
|
||||
|
||||
g_signal_connect(G_OBJECT(w->priv.window), "destroy",
|
||||
G_CALLBACK(webview_destroy_cb), w);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WEBVIEW_API int webview_loop(struct webview *w, int blocking)
|
||||
{
|
||||
gtk_main_iteration_do(blocking);
|
||||
return w->priv.should_exit;
|
||||
}
|
||||
|
||||
WEBVIEW_API void webview_set_title(struct webview *w, const char *title)
|
||||
{
|
||||
gtk_window_set_title(GTK_WINDOW(w->priv.window), title);
|
||||
}
|
||||
|
||||
WEBVIEW_API void webview_set_fullscreen(struct webview *w, int fullscreen)
|
||||
{
|
||||
if (fullscreen)
|
||||
{
|
||||
gtk_window_fullscreen(GTK_WINDOW(w->priv.window));
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_window_unfullscreen(GTK_WINDOW(w->priv.window));
|
||||
}
|
||||
}
|
||||
|
||||
WEBVIEW_API void webview_set_color(struct webview *w, uint8_t r, uint8_t g,
|
||||
uint8_t b, uint8_t a)
|
||||
{
|
||||
GdkRGBA color = {r / 255.0, g / 255.0, b / 255.0, a / 255.0};
|
||||
webkit_web_view_set_background_color(WEBKIT_WEB_VIEW(w->priv.webview),
|
||||
&color);
|
||||
}
|
||||
|
||||
WEBVIEW_API void webview_dialog(struct webview *w,
|
||||
enum webview_dialog_type dlgtype, int flags,
|
||||
const char *title, const char *arg,
|
||||
char *result, size_t resultsz, char *filter)
|
||||
{
|
||||
GtkWidget *dlg;
|
||||
if (result != NULL)
|
||||
{
|
||||
result[0] = '\0';
|
||||
}
|
||||
if (dlgtype == WEBVIEW_DIALOG_TYPE_OPEN ||
|
||||
dlgtype == WEBVIEW_DIALOG_TYPE_SAVE)
|
||||
{
|
||||
dlg = gtk_file_chooser_dialog_new(
|
||||
title, GTK_WINDOW(w->priv.window),
|
||||
(dlgtype == WEBVIEW_DIALOG_TYPE_OPEN
|
||||
? (flags & WEBVIEW_DIALOG_FLAG_DIRECTORY
|
||||
? GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
|
||||
: GTK_FILE_CHOOSER_ACTION_OPEN)
|
||||
: GTK_FILE_CHOOSER_ACTION_SAVE),
|
||||
"_Cancel", GTK_RESPONSE_CANCEL,
|
||||
(dlgtype == WEBVIEW_DIALOG_TYPE_OPEN ? "_Open" : "_Save"),
|
||||
GTK_RESPONSE_ACCEPT, NULL);
|
||||
if (filter[0] != '\0') {
|
||||
GtkFileFilter *file_filter = gtk_file_filter_new();
|
||||
gchar **filters = g_strsplit(filter, ",", -1);
|
||||
gint i;
|
||||
for(i = 0; filters && filters[i]; i++) {
|
||||
gtk_file_filter_add_pattern(file_filter, filters[i]);
|
||||
}
|
||||
gtk_file_filter_set_name(file_filter, filter);
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dlg), file_filter);
|
||||
g_strfreev(filters);
|
||||
}
|
||||
gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dlg), FALSE);
|
||||
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dlg), FALSE);
|
||||
gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dlg), TRUE);
|
||||
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dlg), TRUE);
|
||||
gtk_file_chooser_set_create_folders(GTK_FILE_CHOOSER(dlg), TRUE);
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(dlg));
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg));
|
||||
g_strlcpy(result, filename, resultsz);
|
||||
g_free(filename);
|
||||
}
|
||||
gtk_widget_destroy(dlg);
|
||||
}
|
||||
else if (dlgtype == WEBVIEW_DIALOG_TYPE_ALERT)
|
||||
{
|
||||
GtkMessageType type = GTK_MESSAGE_OTHER;
|
||||
switch (flags & WEBVIEW_DIALOG_FLAG_ALERT_MASK)
|
||||
{
|
||||
case WEBVIEW_DIALOG_FLAG_INFO:
|
||||
type = GTK_MESSAGE_INFO;
|
||||
break;
|
||||
case WEBVIEW_DIALOG_FLAG_WARNING:
|
||||
type = GTK_MESSAGE_WARNING;
|
||||
break;
|
||||
case WEBVIEW_DIALOG_FLAG_ERROR:
|
||||
type = GTK_MESSAGE_ERROR;
|
||||
break;
|
||||
}
|
||||
dlg = gtk_message_dialog_new(GTK_WINDOW(w->priv.window), GTK_DIALOG_MODAL,
|
||||
type, GTK_BUTTONS_OK, "%s", title);
|
||||
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dlg), "%s",
|
||||
arg);
|
||||
gtk_dialog_run(GTK_DIALOG(dlg));
|
||||
gtk_widget_destroy(dlg);
|
||||
}
|
||||
}
|
||||
|
||||
static void webview_eval_finished(GObject *object, GAsyncResult *result,
|
||||
gpointer userdata)
|
||||
{
|
||||
(void)object;
|
||||
(void)result;
|
||||
struct webview *w = (struct webview *)userdata;
|
||||
w->priv.js_busy = 0;
|
||||
}
|
||||
|
||||
WEBVIEW_API int webview_eval(struct webview *w, const char *js)
|
||||
{
|
||||
while (w->priv.ready == 0)
|
||||
{
|
||||
g_main_context_iteration(NULL, TRUE);
|
||||
}
|
||||
w->priv.js_busy = 1;
|
||||
webkit_web_view_run_javascript(WEBKIT_WEB_VIEW(w->priv.webview), js, NULL,
|
||||
webview_eval_finished, w);
|
||||
while (w->priv.js_busy)
|
||||
{
|
||||
g_main_context_iteration(NULL, TRUE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gboolean webview_dispatch_wrapper(gpointer userdata)
|
||||
{
|
||||
struct webview *w = (struct webview *)userdata;
|
||||
for (;;)
|
||||
{
|
||||
struct webview_dispatch_arg *arg =
|
||||
(struct webview_dispatch_arg *)g_async_queue_try_pop(w->priv.queue);
|
||||
if (arg == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
(arg->fn)(w, arg->arg);
|
||||
g_free(arg);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WEBVIEW_API void webview_dispatch(struct webview *w, webview_dispatch_fn fn,
|
||||
void *arg)
|
||||
{
|
||||
struct webview_dispatch_arg *context =
|
||||
(struct webview_dispatch_arg *)g_new(struct webview_dispatch_arg *, 1);
|
||||
context->w = w;
|
||||
context->arg = arg;
|
||||
context->fn = fn;
|
||||
g_async_queue_lock(w->priv.queue);
|
||||
g_async_queue_push_unlocked(w->priv.queue, context);
|
||||
if (g_async_queue_length_unlocked(w->priv.queue) == 1)
|
||||
{
|
||||
gdk_threads_add_idle(webview_dispatch_wrapper, w);
|
||||
}
|
||||
g_async_queue_unlock(w->priv.queue);
|
||||
}
|
||||
|
||||
WEBVIEW_API void webview_terminate(struct webview *w)
|
||||
{
|
||||
w->priv.should_exit = 1;
|
||||
}
|
||||
|
||||
WEBVIEW_API void webview_exit(struct webview *w) { (void)w; }
|
||||
WEBVIEW_API void webview_print_log(const char *s)
|
||||
{
|
||||
fprintf(stderr, "%s\n", s);
|
||||
}
|
||||
|
||||
#endif /* WEBVIEW_GTK */
|
||||
|
||||
#if defined(WEBVIEW_WINAPI)
|
||||
|
||||
#pragma comment(lib, "user32.lib")
|
||||
@@ -1930,433 +1599,6 @@ struct webview_priv
|
||||
WEBVIEW_API void webview_exit(struct webview *w) { OleUninitialize(); }
|
||||
WEBVIEW_API void webview_print_log(const char *s) { OutputDebugString(s); }
|
||||
|
||||
#endif /* WEBVIEW_WINAPI */
|
||||
|
||||
#if defined(WEBVIEW_COCOA)
|
||||
#if (!defined MAC_OS_X_VERSION_10_12) || \
|
||||
MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12
|
||||
#define NSAlertStyleWarning NSWarningAlertStyle
|
||||
#define NSAlertStyleCritical NSCriticalAlertStyle
|
||||
#define NSWindowStyleMaskResizable NSResizableWindowMask
|
||||
#define NSWindowStyleMaskMiniaturizable NSMiniaturizableWindowMask
|
||||
#define NSWindowStyleMaskTitled NSTitledWindowMask
|
||||
#define NSWindowStyleMaskClosable NSClosableWindowMask
|
||||
#define NSWindowStyleMaskFullScreen NSFullScreenWindowMask
|
||||
#define NSEventMaskAny NSAnyEventMask
|
||||
#define NSEventModifierFlagCommand NSCommandKeyMask
|
||||
#define NSEventModifierFlagOption NSAlternateKeyMask
|
||||
#define NSAlertStyleInformational NSInformationalAlertStyle
|
||||
#endif /* MAC_OS_X_VERSION_10_12 */
|
||||
#if (!defined MAC_OS_X_VERSION_10_13) || \
|
||||
MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_13
|
||||
#define NSModalResponseOK NSFileHandlingPanelOKButton
|
||||
#endif /* MAC_OS_X_VERSION_10_12, MAC_OS_X_VERSION_10_13 */
|
||||
static void webview_window_will_close(id self, SEL cmd, id notification)
|
||||
{
|
||||
struct webview *w =
|
||||
(struct webview *)objc_getAssociatedObject(self, "webview");
|
||||
webview_terminate(w);
|
||||
}
|
||||
|
||||
static BOOL webview_is_selector_excluded_from_web_script(id self, SEL cmd,
|
||||
SEL selector)
|
||||
{
|
||||
return selector != @selector(invoke:);
|
||||
}
|
||||
|
||||
static NSString *webview_webscript_name_for_selector(id self, SEL cmd,
|
||||
SEL selector)
|
||||
{
|
||||
return selector == @selector(invoke:) ? @"invoke" : nil;
|
||||
}
|
||||
|
||||
static void webview_did_clear_window_object(id self, SEL cmd, id webview,
|
||||
id script, id frame)
|
||||
{
|
||||
[script setValue:self forKey:@"external"];
|
||||
}
|
||||
|
||||
static void webview_run_input_open_panel(id self, SEL cmd, id webview,
|
||||
id listener, BOOL allowMultiple)
|
||||
{
|
||||
char filename[256] = "";
|
||||
struct webview *w =
|
||||
(struct webview *)objc_getAssociatedObject(self, "webview");
|
||||
|
||||
webview_dialog(w, WEBVIEW_DIALOG_TYPE_OPEN, WEBVIEW_DIALOG_FLAG_FILE, "", "",
|
||||
filename, 255, "");
|
||||
filename[255] = '\0';
|
||||
if (strlen(filename) > 0)
|
||||
{
|
||||
[listener chooseFilename:[NSString stringWithUTF8String:filename]];
|
||||
}
|
||||
else
|
||||
{
|
||||
[listener cancel];
|
||||
}
|
||||
}
|
||||
|
||||
static void webview_external_invoke(id self, SEL cmd, id arg)
|
||||
{
|
||||
struct webview *w =
|
||||
(struct webview *)objc_getAssociatedObject(self, "webview");
|
||||
if (w == NULL || w->external_invoke_cb == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ([arg isKindOfClass:[NSString class]] == NO)
|
||||
{
|
||||
return;
|
||||
}
|
||||
w->external_invoke_cb(w, [(NSString *)(arg) UTF8String]);
|
||||
}
|
||||
|
||||
WEBVIEW_API int webview_init(struct webview *w)
|
||||
{
|
||||
w->priv.pool = [[NSAutoreleasePool alloc] init];
|
||||
[NSApplication sharedApplication];
|
||||
|
||||
Class webViewDelegateClass =
|
||||
objc_allocateClassPair([NSObject class], "WebViewDelegate", 0);
|
||||
class_addMethod(webViewDelegateClass, sel_registerName("windowWillClose:"),
|
||||
(IMP)webview_window_will_close, "v@:@");
|
||||
class_addMethod(object_getClass(webViewDelegateClass),
|
||||
sel_registerName("isSelectorExcludedFromWebScript:"),
|
||||
(IMP)webview_is_selector_excluded_from_web_script, "c@::");
|
||||
class_addMethod(object_getClass(webViewDelegateClass),
|
||||
sel_registerName("webScriptNameForSelector:"),
|
||||
(IMP)webview_webscript_name_for_selector, "c@::");
|
||||
class_addMethod(webViewDelegateClass,
|
||||
sel_registerName("webView:didClearWindowObject:forFrame:"),
|
||||
(IMP)webview_did_clear_window_object, "v@:@@@");
|
||||
class_addMethod(
|
||||
webViewDelegateClass,
|
||||
sel_registerName("webView:runOpenPanelForFileButtonWithResultListener:"
|
||||
"allowMultipleFiles:"),
|
||||
(IMP)webview_run_input_open_panel, "v@:@@c");
|
||||
class_addMethod(webViewDelegateClass, sel_registerName("invoke:"),
|
||||
(IMP)webview_external_invoke, "v@:@");
|
||||
objc_registerClassPair(webViewDelegateClass);
|
||||
|
||||
w->priv.delegate = [[webViewDelegateClass alloc] init];
|
||||
objc_setAssociatedObject(w->priv.delegate, "webview", (id)(w),
|
||||
OBJC_ASSOCIATION_ASSIGN);
|
||||
|
||||
NSRect r = NSMakeRect(0, 0, w->width, w->height);
|
||||
NSUInteger style = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
|
||||
NSWindowStyleMaskMiniaturizable;
|
||||
if (w->resizable)
|
||||
{
|
||||
style = style | NSWindowStyleMaskResizable;
|
||||
// style = style | NSTexturedBackgroundWindowMask;
|
||||
// style = style | NSUnifiedTitleAndToolbarWindowMask;
|
||||
}
|
||||
|
||||
// Transparent title bar
|
||||
// if (w->transparentTitlebar) {
|
||||
// style = style | NSFullSizeContentViewWindowMask | NSUnifiedTitleAndToolbarWindowMask | NSTexturedBackgroundWindowMask;
|
||||
// }
|
||||
|
||||
w->priv.window = [[NSWindow alloc] initWithContentRect:r
|
||||
styleMask:style
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO];
|
||||
[w->priv.window autorelease];
|
||||
|
||||
// Title
|
||||
NSString *nsTitle = [NSString stringWithUTF8String:w->title];
|
||||
[w->priv.window setTitle:nsTitle];
|
||||
|
||||
[w->priv.window setDelegate:w->priv.delegate];
|
||||
[w->priv.window center];
|
||||
|
||||
// NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"wat"];
|
||||
// toolbar.showsBaselineSeparator = NO;
|
||||
// [w->priv.window setToolbar:toolbar];
|
||||
|
||||
// if (w->transparentTitlebar) {
|
||||
|
||||
// // Configure window look with hidden toolbar
|
||||
// [w->priv.window setTitlebarAppearsTransparent:YES];
|
||||
// [w->priv.window setTitleVisibility:NSWindowTitleHidden];
|
||||
// // w->priv.window.isMovableByWindowBackground = true;
|
||||
// }
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] setBool:!!w->debug
|
||||
forKey:@"WebKitDeveloperExtras"];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
w->priv.webview =
|
||||
[[WebView alloc] initWithFrame:r
|
||||
frameName:@"WebView"
|
||||
groupName:nil];
|
||||
NSURL *nsURL = [NSURL
|
||||
URLWithString:[NSString stringWithUTF8String:webview_check_url(w->url)]];
|
||||
[[w->priv.webview mainFrame] loadRequest:[NSURLRequest requestWithURL:nsURL]];
|
||||
|
||||
[w->priv.webview setAutoresizesSubviews:YES];
|
||||
[w->priv.webview
|
||||
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||
w->priv.webview.frameLoadDelegate = w->priv.delegate;
|
||||
w->priv.webview.UIDelegate = w->priv.delegate;
|
||||
[[w->priv.window contentView] addSubview:w->priv.webview];
|
||||
[w->priv.window orderFrontRegardless];
|
||||
|
||||
// Disable scrolling - make this configurable
|
||||
// [[[w->priv.webview mainFrame] frameView] setAllowsScrolling:NO];
|
||||
|
||||
// ----> Enables WebGL but won't pass the app store guidelines
|
||||
//
|
||||
// WebPreferences *p = [w->priv.webview preferences];
|
||||
// if ([p respondsToSelector:@selector(setWebGLEnabled:)]) {
|
||||
// [p setWebGLEnabled:YES];
|
||||
// }
|
||||
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
[NSApp finishLaunching];
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
||||
NSMenu *menubar = [[[NSMenu alloc] initWithTitle:@""] autorelease];
|
||||
|
||||
NSMenuItem *appMenuItem =
|
||||
[[[NSMenuItem alloc] initWithTitle:@"wails app" action:NULL keyEquivalent:@""]
|
||||
autorelease];
|
||||
NSMenu *appMenu = [[[NSMenu alloc] initWithTitle:@"wails app"] autorelease];
|
||||
[appMenuItem setSubmenu:appMenu];
|
||||
[menubar addItem:appMenuItem];
|
||||
|
||||
NSMenuItem *item = [[[NSMenuItem alloc] initWithTitle:@"Hide"
|
||||
action:@selector(hide:)
|
||||
keyEquivalent:@"h"] autorelease];
|
||||
[appMenu addItem:item];
|
||||
item = [[[NSMenuItem alloc] initWithTitle:@"Hide Others"
|
||||
action:@selector(hideOtherApplications:)
|
||||
keyEquivalent:@"h"] autorelease];
|
||||
[item setKeyEquivalentModifierMask:(NSEventModifierFlagOption |
|
||||
NSEventModifierFlagCommand)];
|
||||
[appMenu addItem:item];
|
||||
item = [[[NSMenuItem alloc] initWithTitle:@"Show All"
|
||||
action:@selector(unhideAllApplications:)
|
||||
keyEquivalent:@""] autorelease];
|
||||
[appMenu addItem:item];
|
||||
[appMenu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
NSMenuItem *editMenuItem =
|
||||
[[[NSMenuItem alloc] initWithTitle:@"Edit" action:NULL keyEquivalent:@""]
|
||||
autorelease];
|
||||
NSMenu *editMenu = [[[NSMenu alloc] initWithTitle:@"Edit"] autorelease];
|
||||
[editMenuItem setSubmenu:editMenu];
|
||||
[menubar addItem:editMenuItem];
|
||||
|
||||
item = [[[NSMenuItem alloc] initWithTitle:@"Cut"
|
||||
action:@selector(cut:)
|
||||
keyEquivalent:@"x"] autorelease];
|
||||
[editMenu addItem:item];
|
||||
|
||||
item = [[[NSMenuItem alloc] initWithTitle:@"Copy"
|
||||
action:@selector(copy:)
|
||||
keyEquivalent:@"c"] autorelease];
|
||||
[editMenu addItem:item];
|
||||
|
||||
item = [[[NSMenuItem alloc] initWithTitle:@"Paste"
|
||||
action:@selector(paste:)
|
||||
keyEquivalent:@"v"] autorelease];
|
||||
[editMenu addItem:item];
|
||||
|
||||
item = [[[NSMenuItem alloc] initWithTitle:@"Select All"
|
||||
action:@selector(selectAll:)
|
||||
keyEquivalent:@"a"] autorelease];
|
||||
[editMenu addItem:item];
|
||||
|
||||
[appMenu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
item = [[[NSMenuItem alloc] initWithTitle:@"Quit"
|
||||
action:@selector(terminate:)
|
||||
keyEquivalent:@"q"] autorelease];
|
||||
[appMenu addItem:item];
|
||||
|
||||
[NSApp setMainMenu:menubar];
|
||||
|
||||
w->priv.should_exit = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
WEBVIEW_API int webview_loop(struct webview *w, int blocking)
|
||||
{
|
||||
NSDate *until = (blocking ? [NSDate distantFuture] : [NSDate distantPast]);
|
||||
NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny
|
||||
untilDate:until
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue:YES];
|
||||
if (event)
|
||||
{
|
||||
[NSApp sendEvent:event];
|
||||
}
|
||||
return w->priv.should_exit;
|
||||
}
|
||||
|
||||
WEBVIEW_API int webview_eval(struct webview *w, const char *js)
|
||||
{
|
||||
NSString *nsJS = [NSString stringWithUTF8String:js];
|
||||
[[w->priv.webview windowScriptObject] evaluateWebScript:nsJS];
|
||||
return 0;
|
||||
}
|
||||
|
||||
WEBVIEW_API void webview_set_title(struct webview *w, const char *title)
|
||||
{
|
||||
NSString *nsTitle = [NSString stringWithUTF8String:title];
|
||||
[w->priv.window setTitle:nsTitle];
|
||||
}
|
||||
|
||||
WEBVIEW_API void webview_set_fullscreen(struct webview *w, int fullscreen)
|
||||
{
|
||||
int b = ((([w->priv.window styleMask] & NSWindowStyleMaskFullScreen) ==
|
||||
NSWindowStyleMaskFullScreen)
|
||||
? 1
|
||||
: 0);
|
||||
if (b != fullscreen)
|
||||
{
|
||||
[w->priv.window toggleFullScreen:nil];
|
||||
}
|
||||
}
|
||||
|
||||
WEBVIEW_API void webview_set_color(struct webview *w, uint8_t r, uint8_t g,
|
||||
uint8_t b, uint8_t a)
|
||||
{
|
||||
[w->priv.window setBackgroundColor:[NSColor colorWithRed:(CGFloat)r / 255.0
|
||||
green:(CGFloat)g / 255.0
|
||||
blue:(CGFloat)b / 255.0
|
||||
alpha:(CGFloat)a / 255.0]];
|
||||
if (0.5 >= ((r / 255.0 * 299.0) + (g / 255.0 * 587.0) + (b / 255.0 * 114.0)) /
|
||||
1000.0)
|
||||
{
|
||||
[w->priv.window
|
||||
setAppearance:[NSAppearance
|
||||
appearanceNamed:NSAppearanceNameVibrantDark]];
|
||||
}
|
||||
else
|
||||
{
|
||||
[w->priv.window
|
||||
setAppearance:[NSAppearance
|
||||
appearanceNamed:NSAppearanceNameVibrantLight]];
|
||||
}
|
||||
[w->priv.window setOpaque:NO];
|
||||
[w->priv.window setTitlebarAppearsTransparent:YES];
|
||||
[w->priv.webview setDrawsBackground:NO];
|
||||
}
|
||||
|
||||
WEBVIEW_API void webview_dialog(struct webview *w,
|
||||
enum webview_dialog_type dlgtype, int flags,
|
||||
const char *title, const char *arg,
|
||||
char *result, size_t resultsz, char *filter)
|
||||
{
|
||||
if (dlgtype == WEBVIEW_DIALOG_TYPE_OPEN ||
|
||||
dlgtype == WEBVIEW_DIALOG_TYPE_SAVE)
|
||||
{
|
||||
NSSavePanel *panel;
|
||||
NSString *filter_str = [NSString stringWithUTF8String:filter];
|
||||
filter_str = [filter_str stringByReplacingOccurrencesOfString:@"*."
|
||||
withString:@""];
|
||||
NSArray *fileTypes = [filter_str componentsSeparatedByString:@","];
|
||||
if (dlgtype == WEBVIEW_DIALOG_TYPE_OPEN)
|
||||
{
|
||||
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
|
||||
if (flags & WEBVIEW_DIALOG_FLAG_DIRECTORY)
|
||||
{
|
||||
[openPanel setCanChooseFiles:NO];
|
||||
[openPanel setCanChooseDirectories:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
[openPanel setCanChooseFiles:YES];
|
||||
[openPanel setCanChooseDirectories:NO];
|
||||
if(filter[0] != NULL)
|
||||
{
|
||||
[openPanel setAllowedFileTypes:fileTypes];
|
||||
}
|
||||
}
|
||||
[openPanel setResolvesAliases:NO];
|
||||
[openPanel setAllowsMultipleSelection:NO];
|
||||
panel = openPanel;
|
||||
}
|
||||
else
|
||||
{
|
||||
panel = [NSSavePanel savePanel];
|
||||
}
|
||||
[panel setCanCreateDirectories:YES];
|
||||
[panel setShowsHiddenFiles:YES];
|
||||
[panel setExtensionHidden:NO];
|
||||
[panel setCanSelectHiddenExtension:NO];
|
||||
if(filter[0] != NULL)
|
||||
{
|
||||
[panel setAllowedFileTypes:fileTypes];
|
||||
}
|
||||
[panel setTreatsFilePackagesAsDirectories:YES];
|
||||
[panel beginSheetModalForWindow:w->priv.window
|
||||
completionHandler:^(NSInteger result) {
|
||||
[NSApp stopModalWithCode:result];
|
||||
}];
|
||||
if ([NSApp runModalForWindow:panel] == NSModalResponseOK)
|
||||
{
|
||||
const char *filename = [[[panel URL] path] UTF8String];
|
||||
strlcpy(result, filename, resultsz);
|
||||
}
|
||||
}
|
||||
else if (dlgtype == WEBVIEW_DIALOG_TYPE_ALERT)
|
||||
{
|
||||
NSAlert *a = [NSAlert new];
|
||||
switch (flags & WEBVIEW_DIALOG_FLAG_ALERT_MASK)
|
||||
{
|
||||
case WEBVIEW_DIALOG_FLAG_INFO:
|
||||
[a setAlertStyle:NSAlertStyleInformational];
|
||||
break;
|
||||
case WEBVIEW_DIALOG_FLAG_WARNING:
|
||||
NSLog(@"warning");
|
||||
[a setAlertStyle:NSAlertStyleWarning];
|
||||
break;
|
||||
case WEBVIEW_DIALOG_FLAG_ERROR:
|
||||
NSLog(@"error");
|
||||
[a setAlertStyle:NSAlertStyleCritical];
|
||||
break;
|
||||
}
|
||||
[a setShowsHelp:NO];
|
||||
[a setShowsSuppressionButton:NO];
|
||||
[a setMessageText:[NSString stringWithUTF8String:title]];
|
||||
[a setInformativeText:[NSString stringWithUTF8String:arg]];
|
||||
[a addButtonWithTitle:@"OK"];
|
||||
[a runModal];
|
||||
[a release];
|
||||
}
|
||||
}
|
||||
|
||||
static void webview_dispatch_cb(void *arg)
|
||||
{
|
||||
struct webview_dispatch_arg *context = (struct webview_dispatch_arg *)arg;
|
||||
(context->fn)(context->w, context->arg);
|
||||
free(context);
|
||||
}
|
||||
|
||||
WEBVIEW_API void webview_dispatch(struct webview *w, webview_dispatch_fn fn,
|
||||
void *arg)
|
||||
{
|
||||
struct webview_dispatch_arg *context = (struct webview_dispatch_arg *)malloc(
|
||||
sizeof(struct webview_dispatch_arg));
|
||||
context->w = w;
|
||||
context->arg = arg;
|
||||
context->fn = fn;
|
||||
dispatch_async_f(dispatch_get_main_queue(), context, webview_dispatch_cb);
|
||||
}
|
||||
|
||||
WEBVIEW_API void webview_terminate(struct webview *w)
|
||||
{
|
||||
w->priv.should_exit = 1;
|
||||
}
|
||||
WEBVIEW_API void webview_exit(struct webview *w) { [NSApp terminate:NSApp]; }
|
||||
WEBVIEW_API void webview_print_log(const char *s) { NSLog(@"%s", s); }
|
||||
|
||||
#endif /* WEBVIEW_COCOA */
|
||||
|
||||
#endif /* WEBVIEW_IMPLEMENTATION */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user