Example #1
0
        public static void Initialize()
        {
            if (!s_gtkInitialized)
            {
                try
                {
                    X11.XInitThreads();
                }catch {}
                Resolver.Resolve();
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    using (var backends = new Utf8Buffer("x11"))
                        Native.GdkSetAllowedBackends?.Invoke(backends);
                }
                Native.GtkInit(0, IntPtr.Zero);
                var disp = Native.GdkGetDefaultDisplay();
                DisplayClassName =
                    Utf8Buffer.StringFromPtr(Native.GTypeName(Marshal.ReadIntPtr(Marshal.ReadIntPtr(disp))));

                using (var utf = new Utf8Buffer("avalonia.app." + Guid.NewGuid()))
                    App = Native.GtkApplicationNew(utf, 0);
                //Mark current thread as UI thread
                s_tlsMarker      = true;
                s_gtkInitialized = true;
            }
            AvaloniaLocator.CurrentMutable.Bind <IWindowingPlatform>().ToConstant(Instance)
            .Bind <IClipboard>().ToSingleton <ClipboardImpl>()
            .Bind <IStandardCursorFactory>().ToConstant(new CursorFactory())
            .Bind <IKeyboardDevice>().ToConstant(Keyboard)
            .Bind <IPlatformSettings>().ToConstant(Instance)
            .Bind <IPlatformThreadingInterface>().ToConstant(Instance)
            .Bind <ISystemDialogImpl>().ToSingleton <SystemDialog>()
            .Bind <IRenderLoop>().ToConstant(new DefaultRenderLoop(60))
            .Bind <IPlatformIconLoader>().ToConstant(new PlatformIconLoader());
        }
Example #2
0
        static void OnText(IntPtr clipboard, IntPtr utf8string, IntPtr userdata)
        {
            var handle = GCHandle.FromIntPtr(userdata);

            ((TaskCompletionSource <string>)handle.Target)
            .TrySetResult(Utf8Buffer.StringFromPtr(utf8string));
            handle.Free();
        }
Example #3
0
        public static void Initialize(Gtk3PlatformOptions options)
        {
            Resolver.Custom      = options.CustomResolver;
            UseDeferredRendering = EnvOption("USE_DEFERRED_RENDERING", true, options.UseDeferredRendering);
            var useGpu = EnvOption("USE_GPU", false, options.UseGpuAcceleration);

            if (!s_gtkInitialized)
            {
                try
                {
                    X11.XInitThreads();
                }catch {}
                Resolver.Resolve();
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    using (var backends = new Utf8Buffer("x11"))
                        Native.GdkSetAllowedBackends?.Invoke(backends);
                }
                Native.GtkInit(0, IntPtr.Zero);
                var disp = Native.GdkGetDefaultDisplay();
                DisplayClassName =
                    Utf8Buffer.StringFromPtr(Native.GTypeName(Marshal.ReadIntPtr(Marshal.ReadIntPtr(disp))));

                using (var utf = new Utf8Buffer("avalonia.app." + Guid.NewGuid()))
                    App = Native.GtkApplicationNew(utf, 0);
                //Mark current thread as UI thread
                s_tlsMarker      = true;
                s_gtkInitialized = true;
            }
            AvaloniaLocator.CurrentMutable.Bind <IWindowingPlatform>().ToConstant(Instance)
            .Bind <IClipboard>().ToSingleton <ClipboardImpl>()
            .Bind <IStandardCursorFactory>().ToConstant(new CursorFactory())
            .Bind <IKeyboardDevice>().ToConstant(Keyboard)
            .Bind <IPlatformSettings>().ToConstant(Instance)
            .Bind <IPlatformThreadingInterface>().ToConstant(Instance)
            .Bind <ISystemDialogImpl>().ToSingleton <SystemDialog>()
            .Bind <IRenderLoop>().ToConstant(new RenderLoop())
            .Bind <IRenderTimer>().ToConstant(new DefaultRenderTimer(60))
            .Bind <PlatformHotkeyConfiguration>().ToSingleton <PlatformHotkeyConfiguration>()
            .Bind <IPlatformIconLoader>().ToConstant(new PlatformIconLoader());
            if (useGpu)
            {
                EglGlPlatformFeature.TryInitialize();
            }
        }
Example #4
0
        public static void Initialize()
        {
            Resolver.Resolve();
            Native.GtkInit(0, IntPtr.Zero);
            var disp = Native.GdkGetDefaultDisplay();

            DisplayClassName = Utf8Buffer.StringFromPtr(Native.GTypeName(Marshal.ReadIntPtr(Marshal.ReadIntPtr(disp))));

            using (var utf = new Utf8Buffer("avalonia.app." + Guid.NewGuid()))
                App = Native.GtkApplicationNew(utf, 0);
            //Mark current thread as UI thread
            s_tlsMarker = true;

            AvaloniaLocator.CurrentMutable.Bind <IWindowingPlatform>().ToConstant(Instance)
            .Bind <IClipboard>().ToSingleton <ClipboardImpl>()
            .Bind <IStandardCursorFactory>().ToConstant(new CursorFactory())
            .Bind <IKeyboardDevice>().ToConstant(Keyboard)
            .Bind <IPlatformSettings>().ToConstant(Instance)
            .Bind <IPlatformThreadingInterface>().ToConstant(Instance)
            .Bind <ISystemDialogImpl>().ToSingleton <SystemDialog>()
            .Bind <IRenderLoop>().ToConstant(new DefaultRenderLoop(60))
            .Bind <IPlatformIconLoader>().ToConstant(new PlatformIconLoader());
        }
Example #5
0
        public unsafe static Task <string[]> ShowDialog(string title, GtkWindow parent, GtkFileChooserAction action,
                                                        bool multiselect, string initialFileName, Action <GtkFileChooser> modify)
        {
            GtkFileChooser dlg;

            parent = parent ?? GtkWindow.Null;
            using (var name = new Utf8Buffer(title))
                dlg = Native.GtkFileChooserDialogNew(name, parent, action, IntPtr.Zero);
            modify?.Invoke(dlg);
            if (multiselect)
            {
                Native.GtkFileChooserSetSelectMultiple(dlg, true);
            }

            Native.GtkWindowSetModal(dlg, true);
            var tcs = new TaskCompletionSource <string[]>();
            List <IDisposable> disposables = null;
            Action             dispose     = () =>
            {
                // ReSharper disable once PossibleNullReferenceException
                foreach (var d in disposables)
                {
                    d.Dispose();
                }
                disposables.Clear();
            };

            disposables = new List <IDisposable>
            {
                Signal.Connect <Native.D.signal_generic>(dlg, "close", delegate
                {
                    tcs.TrySetResult(null);
                    dispose();
                    return(false);
                }),
                Signal.Connect <Native.D.signal_dialog_response>(dlg, "response", (_, resp, __) =>
                {
                    string[] result = null;
                    if (resp == GtkResponseType.Accept)
                    {
                        var rlst = new List <string>();
                        var gs   = Native.GtkFileChooserGetFilenames(dlg);
                        var cgs  = gs;
                        while (cgs != null)
                        {
                            if (cgs->Data != IntPtr.Zero)
                            {
                                rlst.Add(Utf8Buffer.StringFromPtr(cgs->Data));
                            }
                            cgs = cgs->Next;
                        }

                        Native.GSlistFree(gs);
                        result = rlst.ToArray();
                    }

                    Native.GtkWidgetHide(dlg);
                    dispose();
                    tcs.TrySetResult(result);
                    return(false);
                }),
                dlg
            };
            using (var open = new Utf8Buffer("Open"))
                Native.GtkDialogAddButton(dlg, open, GtkResponseType.Accept);
            using (var open = new Utf8Buffer("Cancel"))
                Native.GtkDialogAddButton(dlg, open, GtkResponseType.Cancel);
            if (initialFileName != null)
            {
                using (var fn = new Utf8Buffer(initialFileName))
                    Native.GtkFileChooserSetFilename(dlg, fn);
            }
            Native.GtkWindowPresent(dlg);
            return(tcs.Task);
        }
Example #6
0
 private unsafe bool OnCommit(IntPtr gtkwidget, IntPtr utf8string, IntPtr userdata)
 {
     Input(new RawTextInputEventArgs(Gtk3Platform.Keyboard, _lastKbdEvent, Utf8Buffer.StringFromPtr(utf8string)));
     return(true);
 }
Example #7
0
        private unsafe Task <string[]> ShowDialog(string title, IWindowImpl parent, GtkFileChooserAction action,
                                                  bool multiSelect, string initialFileName, IEnumerable <FileDialogFilter> filters, string defaultExtension, bool overwritePrompt)
        {
            IntPtr dlg;

            using (var name = new Utf8Buffer(title))
                dlg = gtk_file_chooser_dialog_new(name, IntPtr.Zero, action, IntPtr.Zero);
            UpdateParent(dlg, parent);
            if (multiSelect)
            {
                gtk_file_chooser_set_select_multiple(dlg, true);
            }

            gtk_window_set_modal(dlg, true);
            var tcs = new TaskCompletionSource <string[]>();
            List <IDisposable> disposables = null;

            void Dispose()
            {
                // ReSharper disable once PossibleNullReferenceException
                foreach (var d in disposables)
                {
                    d.Dispose();
                }
                disposables.Clear();
            }

            var filtersDic = new Dictionary <IntPtr, FileDialogFilter>();

            if (filters != null)
            {
                foreach (var f in filters)
                {
                    var filter = gtk_file_filter_new();
                    filtersDic[filter] = f;
                    using (var b = new Utf8Buffer(f.Name))
                        gtk_file_filter_set_name(filter, b);

                    foreach (var e in f.Extensions)
                    {
                        using (var b = new Utf8Buffer("*." + e))
                            gtk_file_filter_add_pattern(filter, b);
                    }

                    gtk_file_chooser_add_filter(dlg, filter);
                }
            }

            disposables = new List <IDisposable>
            {
                ConnectSignal <signal_generic>(dlg, "close", delegate
                {
                    tcs.TrySetResult(null);
                    Dispose();
                    return(false);
                }),
                ConnectSignal <signal_dialog_response>(dlg, "response", (_, resp, __) =>
                {
                    string[] result = null;
                    if (resp == GtkResponseType.Accept)
                    {
                        var resultList = new List <string>();
                        var gs         = gtk_file_chooser_get_filenames(dlg);
                        var cgs        = gs;
                        while (cgs != null)
                        {
                            if (cgs->Data != IntPtr.Zero)
                            {
                                resultList.Add(Utf8Buffer.StringFromPtr(cgs->Data));
                            }
                            cgs = cgs->Next;
                        }
                        g_slist_free(gs);
                        result = resultList.ToArray();

                        // GTK doesn't auto-append the extension, so we need to do that manually
                        if (action == GtkFileChooserAction.Save)
                        {
                            var currentFilter = gtk_file_chooser_get_filter(dlg);
                            filtersDic.TryGetValue(currentFilter, out var selectedFilter);
                            for (var c = 0; c < result.Length; c++)
                            {
                                result[c] = NameWithExtension(result[c], defaultExtension, selectedFilter);
                            }
                        }
                    }

                    gtk_widget_hide(dlg);
                    Dispose();
                    tcs.TrySetResult(result);
                    return(false);
                })
            };
            using (var open = new Utf8Buffer(
                       action == GtkFileChooserAction.Save ? "Save"
                : action == GtkFileChooserAction.SelectFolder ? "Select"
                : "Open"))
                gtk_dialog_add_button(dlg, open, GtkResponseType.Accept);
            using (var open = new Utf8Buffer("Cancel"))
                gtk_dialog_add_button(dlg, open, GtkResponseType.Cancel);
            if (initialFileName != null)
            {
                using (var fn = new Utf8Buffer(initialFileName))
                {
                    if (action == GtkFileChooserAction.Save)
                    {
                        gtk_file_chooser_set_current_name(dlg, fn);
                    }
                    else
                    {
                        gtk_file_chooser_set_filename(dlg, fn);
                    }
                }
            }

            gtk_file_chooser_set_do_overwrite_confirmation(dlg, overwritePrompt);

            gtk_window_present(dlg);
            return(tcs.Task);
        }

        string NameWithExtension(string path, string defaultExtension, FileDialogFilter filter)
        {
            var name = Path.GetFileName(path);

            if (name != null && !name.Contains("."))
            {
                if (filter?.Extensions?.Count > 0)
                {
                    if (defaultExtension != null &&
                        filter.Extensions.Contains(defaultExtension))
                    {
                        return(path + "." + defaultExtension.TrimStart('.'));
                    }

                    var ext = filter.Extensions.FirstOrDefault(x => x != "*");
                    if (ext != null)
                    {
                        return(path + "." + ext.TrimStart('.'));
                    }
                }

                if (defaultExtension != null)
                {
                    path += "." + defaultExtension.TrimStart('.');
                }
            }

            return(path);
        }
        private unsafe Task <string[]> ShowDialog(string title, IWindowImpl parent, GtkFileChooserAction action,
                                                  bool multiSelect, string initialFileName, IEnumerable <FileDialogFilter> filters)
        {
            IntPtr dlg;

            using (var name = new Utf8Buffer(title))
                dlg = gtk_file_chooser_dialog_new(name, IntPtr.Zero, action, IntPtr.Zero);
            UpdateParent(dlg, parent);
            if (multiSelect)
            {
                gtk_file_chooser_set_select_multiple(dlg, true);
            }

            gtk_window_set_modal(dlg, true);
            var tcs = new TaskCompletionSource <string[]>();
            List <IDisposable> disposables = null;

            void Dispose()
            {
                // ReSharper disable once PossibleNullReferenceException
                foreach (var d in disposables)
                {
                    d.Dispose();
                }
                disposables.Clear();
            }

            if (filters != null)
            {
                foreach (var f in filters)
                {
                    var filter = gtk_file_filter_new();
                    using (var b = new Utf8Buffer(f.Name))
                        gtk_file_filter_set_name(filter, b);

                    foreach (var e in f.Extensions)
                    {
                        using (var b = new Utf8Buffer("*." + e))
                            gtk_file_filter_add_pattern(filter, b);
                    }

                    gtk_file_chooser_add_filter(dlg, filter);
                }
            }

            disposables = new List <IDisposable>
            {
                ConnectSignal <signal_generic>(dlg, "close", delegate
                {
                    tcs.TrySetResult(null);
                    Dispose();
                    return(false);
                }),
                ConnectSignal <signal_dialog_response>(dlg, "response", (_, resp, __) =>
                {
                    string[] result = null;
                    if (resp == GtkResponseType.Accept)
                    {
                        var resultList = new List <string>();
                        var gs         = gtk_file_chooser_get_filenames(dlg);
                        var cgs        = gs;
                        while (cgs != null)
                        {
                            if (cgs->Data != IntPtr.Zero)
                            {
                                resultList.Add(Utf8Buffer.StringFromPtr(cgs->Data));
                            }
                            cgs = cgs->Next;
                        }
                        g_slist_free(gs);
                        result = resultList.ToArray();
                    }

                    gtk_widget_hide(dlg);
                    Dispose();
                    tcs.TrySetResult(result);
                    return(false);
                })
            };
            using (var open = new Utf8Buffer(
                       action == GtkFileChooserAction.Save ? "Save"
                : action == GtkFileChooserAction.SelectFolder ? "Select"
                : "Open"))
                gtk_dialog_add_button(dlg, open, GtkResponseType.Accept);
            using (var open = new Utf8Buffer("Cancel"))
                gtk_dialog_add_button(dlg, open, GtkResponseType.Cancel);
            if (initialFileName != null)
            {
                using (var fn = new Utf8Buffer(initialFileName))
                {
                    if (action == GtkFileChooserAction.Save)
                    {
                        gtk_file_chooser_set_current_name(dlg, fn);
                    }
                    else
                    {
                        gtk_file_chooser_set_filename(dlg, fn);
                    }
                }
            }

            gtk_window_present(dlg);
            return(tcs.Task);
        }
        private unsafe Task <string[]?> ShowDialog(string?title, IWindowImpl parent, GtkFileChooserAction action,
                                                   bool multiSelect, IStorageFolder?initialFolder, string?initialFileName,
                                                   IEnumerable <FilePickerFileType>?filters, string?defaultExtension, bool overwritePrompt)
        {
            IntPtr dlg;

            using (var name = new Utf8Buffer(title))
            {
                dlg = gtk_file_chooser_dialog_new(name, IntPtr.Zero, action, IntPtr.Zero);
            }

            UpdateParent(dlg, parent);
            if (multiSelect)
            {
                gtk_file_chooser_set_select_multiple(dlg, true);
            }

            gtk_window_set_modal(dlg, true);
            var tcs = new TaskCompletionSource <string[]?>();
            List <IDisposable>?disposables = null;

            void Dispose()
            {
                foreach (var d in disposables !)
                {
                    d.Dispose();
                }

                disposables.Clear();
            }

            var filtersDic = new Dictionary <IntPtr, FilePickerFileType>();

            if (filters != null)
            {
                foreach (var f in filters)
                {
                    if (f.Patterns?.Any() == true || f.MimeTypes?.Any() == true)
                    {
                        var filter = gtk_file_filter_new();
                        filtersDic[filter] = f;
                        using (var b = new Utf8Buffer(f.Name))
                        {
                            gtk_file_filter_set_name(filter, b);
                        }

                        if (f.Patterns is not null)
                        {
                            foreach (var e in f.Patterns)
                            {
                                using (var b = new Utf8Buffer(e))
                                {
                                    gtk_file_filter_add_pattern(filter, b);
                                }
                            }
                        }

                        if (f.MimeTypes is not null)
                        {
                            foreach (var e in f.MimeTypes)
                            {
                                using (var b = new Utf8Buffer(e))
                                {
                                    gtk_file_filter_add_mime_type(filter, b);
                                }
                            }
                        }

                        gtk_file_chooser_add_filter(dlg, filter);
                    }
                }
            }

            disposables = new List <IDisposable>
            {
                ConnectSignal <signal_generic>(dlg, "close", delegate
                {
                    tcs.TrySetResult(null);
                    Dispose();
                    return(false);
                }),
                ConnectSignal <signal_dialog_response>(dlg, "response", (_, resp, __) =>
                {
                    string[]? result = null;
                    if (resp == GtkResponseType.Accept)
                    {
                        var resultList = new List <string>();
                        var gs         = gtk_file_chooser_get_filenames(dlg);
                        var cgs        = gs;
                        while (cgs != null)
                        {
                            if (cgs->Data != IntPtr.Zero &&
                                Utf8Buffer.StringFromPtr(cgs->Data) is string str)
                            {
                                resultList.Add(str);
                            }
                            cgs = cgs->Next;
                        }
                        g_slist_free(gs);
                        result = resultList.ToArray();

                        // GTK doesn't auto-append the extension, so we need to do that manually
                        if (action == GtkFileChooserAction.Save)
                        {
                            var currentFilter = gtk_file_chooser_get_filter(dlg);
                            filtersDic.TryGetValue(currentFilter, out var selectedFilter);
                            for (var c = 0; c < result.Length; c++)
                            {
                                result[c] = StorageProviderHelpers.NameWithExtension(result[c], defaultExtension, selectedFilter);
                            }
                        }
                    }

                    gtk_widget_hide(dlg);
                    Dispose();
                    tcs.TrySetResult(result);
                    return(false);
                })
            };
            using (var open = new Utf8Buffer(
                       action == GtkFileChooserAction.Save ? "Save"
                : action == GtkFileChooserAction.SelectFolder ? "Select"
                : "Open"))
            {
                gtk_dialog_add_button(dlg, open, GtkResponseType.Accept);
            }

            using (var open = new Utf8Buffer("Cancel"))
            {
                gtk_dialog_add_button(dlg, open, GtkResponseType.Cancel);
            }

            Uri?folderPath = null;

            if (initialFolder?.TryGetUri(out folderPath) == true)
            {
                using var dir = new Utf8Buffer(folderPath.LocalPath);
                gtk_file_chooser_set_current_folder(dlg, dir);
            }

            if (initialFileName != null)
            {
                // gtk_file_chooser_set_filename() expects full path
                using var fn = action == GtkFileChooserAction.Open
                    ? new Utf8Buffer(Path.Combine(folderPath?.LocalPath ?? "", initialFileName))
                    : new Utf8Buffer(initialFileName);

                if (action == GtkFileChooserAction.Save)
                {
                    gtk_file_chooser_set_current_name(dlg, fn);
                }
                else
                {
                    gtk_file_chooser_set_filename(dlg, fn);
                }
            }

            gtk_file_chooser_set_do_overwrite_confirmation(dlg, overwritePrompt);

            gtk_window_present(dlg);
            return(tcs.Task);
        }