示例#1
0
 private void FinishUriSchemeCallback(IntPtr request, IntPtr stream, long streamLength, Uri uri)
 {
     using (GLibString mimetype = Application.ContentProvider.GetMimeType(uri))
     {
         WebKit.UriScheme.FinishSchemeRequest(request, stream, streamLength, mimetype);
     }
 }
示例#2
0
 private static IntPtr CreateHandle(string label)
 {
     using (GLibString glabel = label)
     {
         return(Gtk.Menu.CreateLabelItem(glabel));
     }
 }
示例#3
0
        public DialogResult Show(IWindow?parent)
        {
            var    window = NativeCast.To <GtkWindow>(parent);
            IntPtr dialog = IntPtr.Zero;

            try
            {
                using GLibString title   = Title;
                using GLibString message = Message;
                dialog = Gtk.Dialog.CreateMessageDialog(
                    window?.Handle ?? IntPtr.Zero,
                    GtkDialogFlags.Modal | GtkDialogFlags.DestroyWithParent,
                    GtkMessageType.Other,
                    MapButtons(Buttons),
                    IntPtr.Zero);

                GLib.SetProperty(dialog, "title", title);
                GLib.SetProperty(dialog, "text", message);

                var result = Gtk.Dialog.Run(dialog);
                return(MapResult(result));
            }
            finally { if (dialog != IntPtr.Zero)
                      {
                          Gtk.Widget.Destroy(dialog);
                      }
            }
        }
示例#4
0
 private void FinishUriSchemeCallback(IntPtr request, IntPtr stream, long streamLength, Uri uri)
 {
     using (GLibString mimetype = MimeTypes.FindForUri(uri))
     {
         WebKit.UriScheme.FinishSchemeRequest(request, stream, streamLength, mimetype);
     }
 }
示例#5
0
 protected override void SetShortcut(string shortcut)
 {
     using (GLibString gshortcut = shortcut)
     {
         Gtk.Menu.SetAccelerator(Handle, gshortcut);
     }
 }
示例#6
0
        private void LoadCallback(IntPtr webview, WebKitLoadEvent type, IntPtr userdata)
        {
            if (type == WebKitLoadEvent.Started)
            {
                loadEventHandled = false;
            }

            // this callback gets called in this order:
            // Started: initially defined URL
            // Redirected (optional, multiple): new URL to which the redirect points
            // Committed: final URL that gets loaded, either initial URL or same as last redirect URL
            // Finished: same URL as committed, page has fully loaded
            if (type == WebKitLoadEvent.Started || type == WebKitLoadEvent.Redirected)
            {
                string url  = GLibString.FromPointer(WebKit.GetCurrentUri(webview));
                var    args = new NavigatingEventArgs(new Uri(url));
                Navigating?.Invoke(this, args);
                if (args.Cancel)
                {
                    WebKit.StopLoading(webview);
                }
            }
            else if (type == WebKitLoadEvent.Finished && !loadEventHandled)
            {
                if (EnableDevTools)
                {
                    ShowDevTools();
                }

                loadEventHandled = true;
            }
        }
示例#7
0
        private void SetFileFilters(IntPtr dialog, IEnumerable <FileFilter> filters)
        {
            if (!filters.Any())
            {
                return;
            }

            foreach (var filter in filters)
            {
                var gfilter = Gtk.Dialog.FileFilter.Create();
                using (GLibString name = filter.Name)
                {
                    Gtk.Dialog.FileFilter.SetName(gfilter, name);
                }

                foreach (string filterValue in filter.Filters)
                {
                    using (GLibString value = filterValue)
                    {
                        Gtk.Dialog.FileFilter.AddPattern(gfilter, value);
                    }
                }

                Gtk.Dialog.AddFileFilter(dialog, gfilter);
            }
        }
示例#8
0
        public void SetShortcut(ModifierKey modifier, Key key)
        {
            string shortcut = KeyMapper.GetShortcut(modifier, key);

            using GLibString gshortcut = shortcut;
            Gtk.Menu.SetAccelerator(Handle, gshortcut);
        }
示例#9
0
 public static void ConnectSignal(IntPtr instance, string signalName, Delegate handler, IntPtr data)
 {
     using (GLibString gname = signalName)
     {
         ConnectSignalData(instance, gname, handler, data, IntPtr.Zero, 0);
     }
 }
示例#10
0
        private void UpdateIcon(AppIcon icon)
        {
            string tempPath = null;

            string path;

            if (icon == null || icon.Icons.Length == 0)
            {
                path = DefaultIconName;
            }
            else if (icon.Source == AppIcon.IconSource.File)
            {
                path = icon.DefaultIcon.Path;
            }
            else
            {
                tempPath = Path.GetTempFileName();
                using (var tmpStream = File.Open(tempPath, FileMode.Create))
                    using (var iconStream = icon.GetIconDataStream(icon.DefaultIcon))
                    {
                        iconStream.CopyTo(tmpStream);
                    }

                path = tempPath;
            }

            using (GLibString gpath = path)
            {
                AppIndicator.SetIcon(Handle, gpath);
            }

            ClearTempFile();
            tempIconFile = tempPath;
        }
示例#11
0
 public static void SetProperty(IntPtr obj, string propertyName, IntPtr value)
 {
     using (GLibString gname = propertyName)
     {
         SetProperty(obj, gname, value, IntPtr.Zero);
     }
 }
示例#12
0
        public async Task <string> ExecuteScriptAsync(string script)
        {
            var taskResult = new TaskCompletionSource <string>();
            var id         = Guid.NewGuid();
            GAsyncReadyDelegate callback = (IntPtr webview, IntPtr asyncResult, IntPtr userdata) =>
            {
                try
                {
                    taskResult.SetResult(ExecuteScriptCallback(webview, asyncResult, userdata));
                }
                catch (Exception ex)
                {
                    taskResult.SetException(ex);
                }
            };

            scriptCallbacks.TryAdd(id, callback);

            using (GLibString gfunction = script)
            {
                WebKit.JavaScript.BeginExecute(Handle, gfunction, IntPtr.Zero, callback, IntPtr.Zero);
            }

            // found no other solution than the ConccurentDictionary one to keep the callbacks from getting garbage collected
            // GC.KeepAlive(callback) works not all the time
            var result = await taskResult.Task;

            scriptCallbacks.TryRemove(id, out var _);
            return(result);
        }
示例#13
0
        protected override unsafe void BeforeReturn(IntPtr dialog, DialogResult result)
        {
            base.BeforeReturn(dialog, result);

            var filesPtr = Gtk.Dialog.GetSelectedFiles(dialog);
            var files    = new List <string>();

            if (filesPtr != IntPtr.Zero)
            {
                try
                {
                    var list = Marshal.PtrToStructure <GSList>(filesPtr);
                    while (true)
                    {
                        using (var value = new GLibString(list.Data))
                        {
                            files.Add(value.ToString());
                        }

                        if (list.Next == null)
                        {
                            break;
                        }
                        list = *list.Next;
                    }
                }
                finally { GLib.FreeSList(filesPtr); }
            }

            SelectedFiles = files.ToArray();
        }
 protected override void BeforeShow(IntPtr dialog)
 {
     if (!string.IsNullOrWhiteSpace(SelectedPath))
     {
         using GLibString dir = SelectedPath;
         Gtk.Dialog.SetCurrentFolder(dialog, dir);
     }
 }
示例#15
0
 public GtkStatusIcon(string title)
 {
     // TODO: allow setting App ID and AppIndicatorCategory
     using GLibString id   = $"com.{title}.app";
     using GLibString icon = DefaultIconName;
     Handle = AppIndicator.Create(id, icon, AppIndicatorCategory.ApplicationStatus);
     Title  = title;
 }
示例#16
0
        public Task <string> ExecuteScriptAsync(string script)
        {
            var taskResult = new TaskCompletionSource <string>();

            unsafe void Callback(IntPtr webview, IntPtr asyncResult, IntPtr userdata)
            {
                IntPtr jsResult = IntPtr.Zero;

                try
                {
                    jsResult = WebKit.JavaScript.EndExecute(webview, asyncResult, out IntPtr errorPtr);
                    if (jsResult != IntPtr.Zero)
                    {
                        IntPtr value = WebKit.JavaScript.GetValue(jsResult);
                        if (WebKit.JavaScript.IsValueString(value))
                        {
                            IntPtr bytes    = WebKit.JavaScript.GetStringBytes(value);
                            IntPtr bytesPtr = GLib.GetBytesDataPointer(bytes, out UIntPtr length);

                            string result = Encoding.UTF8.GetString((byte *)bytesPtr, (int)length);
                            taskResult.TrySetResult(result);

                            GLib.UnrefBytes(bytes);
                        }
                        else
                        {
                            taskResult.TrySetResult(null);
                        }
                    }
                    else
                    {
                        try
                        {
                            var    error        = Marshal.PtrToStructure <GError>(errorPtr);
                            string errorMessage = GLibString.FromPointer(error.Message);
                            taskResult.TrySetException(new Exception($"Script execution failed with: \"{errorMessage}\""));
                        }
                        catch (Exception ex) { taskResult.TrySetException(ex); }
                        finally { GLib.FreeError(errorPtr); }
                    }
                }
                catch (Exception ex) { taskResult.TrySetException(ex); }
                finally
                {
                    if (jsResult != IntPtr.Zero)
                    {
                        WebKit.JavaScript.ReleaseJsResult(jsResult);
                    }
                }
            }

            using (GLibString gfunction = script)
            {
                WebKit.JavaScript.BeginExecute(Handle, gfunction, IntPtr.Zero, Callback, IntPtr.Zero);
            }

            return(taskResult.Task);
        }
示例#17
0
 public GtkStatusIcon()
 {
     using (GLibString id = GetAppId())
         using (GLibString icon = DefaultIconName)
         {
             Handle = AppIndicator.Create(id, icon, AppIndicatorCategory.ApplicationStatus);
             AppIndicator.SetTitle(Handle, id);
         }
 }
示例#18
0
        private bool LoadFailedCallback(IntPtr webview, WebKitLoadEvent type, IntPtr failingUrl, IntPtr error, IntPtr userdata)
        {
            // this event is called when there is an error, immediately afterwards the LoadCallback is called with state Finished.
            // to indicate that there was an error and the PageLoaded event has been invoked, the loadEventHandled variable is set to true.
            loadEventHandled = true;
            string url = GLibString.FromPointer(failingUrl);

            PageLoaded?.Invoke(this, new PageLoadEventArgs(new Uri(url), false));

            return(false);
        }
 protected override unsafe void BeforeReturn(IntPtr dialog, DialogResult result)
 {
     if (result == DialogResult.Ok)
     {
         using var folderPath = new GLibString(Gtk.Dialog.GetFileName(dialog));
         SelectedPath         = folderPath.ToString();
     }
     else
     {
         SelectedPath = null;
     }
 }
示例#20
0
        public override void SetAccelGroup(IntPtr accelGroupHandle)
        {
            if (hasShortcut)
            {
                using (GLibString signal = "activate")
                {
                    Gtk.Widget.AddAccelerator(Handle, signal, accelGroupHandle, shortcutKey, shortcutModifierKey, GtkAccelFlags.Visible);
                }
            }

            subMenu.SetAccelGroup(accelGroupHandle);
        }
示例#21
0
 protected override void BeforeReturn(IntPtr dialog, DialogResult result)
 {
     if (result == DialogResult.Ok)
     {
         using var fileName = new GLibString(Gtk.Dialog.GetFileName(dialog));
         FileName           = fileName.ToString();
     }
     else
     {
         FileName = null;
     }
 }
示例#22
0
        public Task <string?> ExecuteScriptAsync(string script)
        {
            var taskResult = new TaskCompletionSource <string?>();
            var data       = new ScriptExecuteState(taskResult);
            var handle     = GCHandle.Alloc(data, GCHandleType.Normal);

            using (GLibString gfunction = script)
            {
                WebKit.JavaScript.BeginExecute(Handle, gfunction, IntPtr.Zero, scriptExecuteCallback, GCHandle.ToIntPtr(handle));
            }

            return(taskResult.Task);
        }
示例#23
0
        private unsafe void ScriptExecuteCallback(IntPtr webview, IntPtr asyncResult, IntPtr userdata)
        {
            var handle = GCHandle.FromIntPtr(userdata);
            var state  = (ScriptExecuteState)handle.Target !;

            IntPtr jsResult = IntPtr.Zero;

            try
            {
                jsResult = WebKit.JavaScript.EndExecute(webview, asyncResult, out IntPtr errorPtr);
                if (jsResult != IntPtr.Zero)
                {
                    IntPtr value = WebKit.JavaScript.GetValue(jsResult);
                    if (WebKit.JavaScript.IsValueString(value))
                    {
                        IntPtr bytes    = WebKit.JavaScript.GetStringBytes(value);
                        IntPtr bytesPtr = GLib.GetBytesDataPointer(bytes, out UIntPtr length);

                        string result = Encoding.UTF8.GetString((byte *)bytesPtr, (int)length);
                        state.TaskResult.TrySetResult(result);

                        GLib.UnrefBytes(bytes);
                    }
                    else
                    {
                        state.TaskResult.TrySetResult(null);
                    }
                }
                else
                {
                    try
                    {
                        var    error        = Marshal.PtrToStructure <GError>(errorPtr);
                        string?errorMessage = GLibString.FromPointer(error.Message);
                        state.TaskResult.TrySetException(new ScriptException($"Script execution failed with: \"{errorMessage}\""));
                    }
                    catch (Exception ex) { state.TaskResult.TrySetException(ex); }
                    finally { GLib.FreeError(errorPtr); }
                }
            }
            catch (Exception ex) { state.TaskResult.TrySetException(ex); }
            finally
            {
                handle.Free();

                if (jsResult != IntPtr.Zero)
                {
                    WebKit.JavaScript.ReleaseJsResult(jsResult);
                }
            }
        }
示例#24
0
        public void LoadUri(Uri uri)
        {
            if (uri == null)
            {
                throw new ArgumentNullException(nameof(uri));
            }

            if (!uri.IsAbsoluteUri)
            {
                uri = new Uri(customHost, uri);
            }

            using GLibString gurl = uri.ToString();
            WebKit.LoadUri(Handle, gurl);
        }
示例#25
0
        public GtkWebview(WebviewBridge bridge)
        {
            this.bridge     = bridge ?? throw new ArgumentNullException(nameof(bridge));
            scriptCallbacks = new ConcurrentDictionary <Guid, GAsyncReadyDelegate>();

            // need to keep the delegates around or they will get garbage collected
            scriptDelegate      = ScriptCallback;
            loadFailedDelegate  = LoadFailedCallback;
            loadDelegate        = LoadCallback;
            contextMenuDelegate = ContextMenuCallback;
            closeDelegate       = CloseCallback;
            titleChangeDelegate = TitleChangeCallback;
            uriSchemeCallback   = UriSchemeCallback;

            manager = WebKit.Manager.Create();
            GLib.ConnectSignal(manager, "script-message-received::external", scriptDelegate, IntPtr.Zero);

            using (GLibString name = "external")
            {
                WebKit.Manager.RegisterScriptMessageHandler(manager, name);
            }

            using (GLibString initScript = Resources.GetInitScript("Linux"))
            {
                var script = WebKit.Manager.CreateScript(initScript, WebKitInjectedFrames.AllFrames, WebKitInjectionTime.DocumentStart, IntPtr.Zero, IntPtr.Zero);
                WebKit.Manager.AddScript(manager, script);
                WebKit.Manager.UnrefScript(script);
            }

            Handle    = WebKit.CreateWithUserContentManager(manager);
            settings  = WebKit.Settings.Get(Handle);
            inspector = WebKit.Inspector.Get(Handle);

            GLib.ConnectSignal(Handle, "load-failed", loadFailedDelegate, IntPtr.Zero);
            GLib.ConnectSignal(Handle, "load-changed", loadDelegate, IntPtr.Zero);
            GLib.ConnectSignal(Handle, "context-menu", contextMenuDelegate, IntPtr.Zero);
            GLib.ConnectSignal(Handle, "close", closeDelegate, IntPtr.Zero);
            GLib.ConnectSignal(Handle, "notify::title", titleChangeDelegate, IntPtr.Zero);

            customHost = new Uri(UriTools.GetRandomResourceUrl(CustomScheme));

            IntPtr context = WebKit.Context.Get(Handle);

            using (GLibString gscheme = CustomScheme)
            {
                WebKit.Context.RegisterUriScheme(context, gscheme, uriSchemeCallback, IntPtr.Zero, IntPtr.Zero);
            }
        }
示例#26
0
        protected override void BeforeShow(IntPtr dialog)
        {
            if (!string.IsNullOrWhiteSpace(InitialDirectory))
            {
                using GLibString dir = InitialDirectory;
                Gtk.Dialog.SetCurrentFolder(dialog, dir);
            }

            if (!string.IsNullOrWhiteSpace(FileName))
            {
                using GLibString name = FileName;
                Gtk.Dialog.SetFileName(dialog, name);
            }

            SetFileFilters(dialog, FileFilters);
        }
示例#27
0
        private string ExecuteScriptCallback(IntPtr webview, IntPtr asyncResult, IntPtr userdata)
        {
            IntPtr jsResult = IntPtr.Zero;

            try
            {
                jsResult = WebKit.JavaScript.EndExecute(webview, asyncResult, out IntPtr errorPtr);
                if (jsResult != IntPtr.Zero)
                {
                    IntPtr value = WebKit.JavaScript.GetValue(jsResult);
                    if (WebKit.JavaScript.IsValueString(value))
                    {
                        IntPtr bytes    = WebKit.JavaScript.GetStringBytes(value);
                        IntPtr bytesPtr = GLib.GetBytesDataPointer(bytes, out UIntPtr length);

                        unsafe
                        {
                            string result = Encoding.UTF8.GetString((byte *)bytesPtr, (int)length);
                            GLib.UnrefBytes(bytes);
                            return(result);
                        }
                    }
                    else
                    {
                        return(null);
                    }
                }
                else
                {
                    try
                    {
                        var    error        = Marshal.PtrToStructure <GError>(errorPtr);
                        string errorMessage = GLibString.FromPointer(error.Message);
                        throw new Exception($"Script execution failed with: \"{errorMessage}\"");
                    }
                    finally { GLib.FreeError(errorPtr); }
                }
            }
            finally
            {
                if (jsResult != IntPtr.Zero)
                {
                    WebKit.JavaScript.ReleaseJsResult(jsResult);
                }
            }
        }
示例#28
0
        public GtkWebview(WebviewBridge bridge)
        {
            this.bridge = bridge ?? throw new ArgumentNullException(nameof(bridge));

            // need to keep the delegates around or they will get garbage collected
            scriptDelegate      = ScriptCallback;
            loadFailedDelegate  = LoadFailedCallback;
            loadDelegate        = LoadCallback;
            contextMenuDelegate = ContextMenuCallback;
            closeDelegate       = CloseCallback;
            titleChangeDelegate = TitleChangeCallback;

            manager = WebKit.Manager.Create();
            GLib.ConnectSignal(manager, "script-message-received::external", scriptDelegate, IntPtr.Zero);

            using (GLibString name = "external")
            {
                WebKit.Manager.RegisterScriptMessageHandler(manager, name);
            }

            Handle    = WebKit.CreateWithUserContentManager(manager);
            settings  = WebKit.Settings.Get(Handle);
            inspector = WebKit.Inspector.Get(Handle);

            GLib.ConnectSignal(Handle, "load-failed", loadFailedDelegate, IntPtr.Zero);
            GLib.ConnectSignal(Handle, "load-changed", loadDelegate, IntPtr.Zero);
            GLib.ConnectSignal(Handle, "context-menu", contextMenuDelegate, IntPtr.Zero);
            GLib.ConnectSignal(Handle, "close", closeDelegate, IntPtr.Zero);
            GLib.ConnectSignal(Handle, "notify::title", titleChangeDelegate, IntPtr.Zero);

            const string scheme = "spidereye";

            customHost = new Uri(UriTools.GetRandomResourceUrl(scheme));

            IntPtr context = WebKit.Context.Get(Handle);

            using (GLibString gscheme = scheme)
            {
                WebKit.Context.RegisterUriScheme(context, gscheme, UriSchemeCallback, IntPtr.Zero, IntPtr.Zero);
            }
        }
示例#29
0
        public void NavigateToFile(string url)
        {
            if (url == null)
            {
                throw new ArgumentNullException(nameof(url));
            }

            if (customHost != null)
            {
                url = UriTools.Combine(customHost, url).ToString();
            }
            else
            {
                url = UriTools.Combine(config.ExternalHost, url).ToString();
            }

            using (GLibString gurl = url)
            {
                WebKit.LoadUri(Handle, gurl);
            }
        }
示例#30
0
        private void SetBackgroundColor(string color)
        {
            IntPtr provider = IntPtr.Zero;

            try
            {
                provider = Gtk.Css.Create();

                using (GLibString css = $"* {{background-color:{color}}}")
                {
                    Gtk.Css.LoadData(provider, css, new IntPtr(-1), IntPtr.Zero);
                }

                IntPtr context = Gtk.StyleContext.Get(Handle);
                Gtk.StyleContext.AddProvider(context, provider, GtkStyleProviderPriority.Application);
            }
            finally { if (provider != IntPtr.Zero)
                      {
                          GLib.UnrefObject(provider);
                      }
            }
        }