From b3dce20c4e5da44f39df6b6a083e62d833ddf57c Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 20 Jun 2019 15:08:31 +0200 Subject: [PATCH 01/11] Remove unused usings. The reference to `Avalonia.Markup.Xaml.PortableXaml` was causing a compile error in ncrunch but not in a normal build for some reason. --- src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs index e8f2439f46..db0b617bcd 100644 --- a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs +++ b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs @@ -2,18 +2,10 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; -using System.Collections.Generic; -using System.ComponentModel; using System.IO; -using System.Linq; using System.Reflection; -using System.Runtime.Serialization; using System.Text; -using System.Xml.Linq; using Avalonia.Markup.Xaml.XamlIl; -using Avalonia.Controls; -using Avalonia.Markup.Data; -using Avalonia.Markup.Xaml.PortableXaml; using Avalonia.Platform; namespace Avalonia.Markup.Xaml From d2f7905262fb43ebd3c7fe87cd145949533ada27 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Fri, 21 Jun 2019 10:26:20 +0300 Subject: [PATCH 02/11] Updated XamlIl --- src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github b/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github index 610cda30c6..894b2c0282 160000 --- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github +++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github @@ -1 +1 @@ -Subproject commit 610cda30c69e32e83c8235060606480904c937bc +Subproject commit 894b2c02827fd5eb16a338de5d5b6c9fbc60fef5 From ebdb66048de9a0eba8ed959bd6ff1a54c3286d24 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 22 Jun 2019 00:00:55 +0300 Subject: [PATCH 03/11] Fixed fbdev --- src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs | 5 ++++- src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebuffer.cs | 4 +--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs b/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs index 43beb923e5..83d1c4aae3 100644 --- a/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs +++ b/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs @@ -45,7 +45,10 @@ namespace Avalonia.Controls.Embedding { if (EnforceClientSize) availableSize = PlatformImpl?.ClientSize ?? default(Size); - return base.MeasureOverride(availableSize); + var rv = base.MeasureOverride(availableSize); + if (EnforceClientSize) + return availableSize; + return rv; } private readonly NameScope _nameScope = new NameScope(); diff --git a/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebuffer.cs b/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebuffer.cs index 87b55be488..1e25bd4a8a 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebuffer.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebuffer.cs @@ -43,12 +43,10 @@ namespace Avalonia.LinuxFramebuffer SetBpp(); - _varInfo.yoffset = 100; if (-1 == NativeUnsafeMethods.ioctl(_fd, FbIoCtl.FBIOPUT_VSCREENINFO, pnfo)) _varInfo.transp = new fb_bitfield(); - if (-1 == NativeUnsafeMethods.ioctl(_fd, FbIoCtl.FBIOPUT_VSCREENINFO, pnfo)) - throw new Exception("FBIOPUT_VSCREENINFO error: " + Marshal.GetLastWin32Error()); + NativeUnsafeMethods.ioctl(_fd, FbIoCtl.FBIOPUT_VSCREENINFO, pnfo); if (-1 == NativeUnsafeMethods.ioctl(_fd, FbIoCtl.FBIOGET_VSCREENINFO, pnfo)) throw new Exception("FBIOGET_VSCREENINFO error: " + Marshal.GetLastWin32Error()); From 9efdffe8753ff012d7e488e4ef294140f92c135b Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 22 Jun 2019 00:02:47 +0300 Subject: [PATCH 04/11] Don't use global variables in ControlCatalog --- .../ControlCatalog/Pages/ContextMenuPage.xaml.cs | 13 +++++++++++++ samples/ControlCatalog/Pages/MenuPage.xaml.cs | 14 ++++++++++++++ .../ViewModels/ContextMenuPageViewModel.cs | 7 ++++++- .../ControlCatalog/ViewModels/MenuPageViewModel.cs | 7 ++++++- 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/samples/ControlCatalog/Pages/ContextMenuPage.xaml.cs b/samples/ControlCatalog/Pages/ContextMenuPage.xaml.cs index 96e8b49f89..f861bfab33 100644 --- a/samples/ControlCatalog/Pages/ContextMenuPage.xaml.cs +++ b/samples/ControlCatalog/Pages/ContextMenuPage.xaml.cs @@ -1,3 +1,4 @@ +using System; using Avalonia.Controls; using Avalonia.Markup.Xaml; using ControlCatalog.ViewModels; @@ -12,6 +13,18 @@ namespace ControlCatalog.Pages DataContext = new ContextMenuPageViewModel(); } + private ContextMenuPageViewModel _model; + protected override void OnDataContextChanged(EventArgs e) + { + if (_model != null) + _model.View = null; + _model = DataContext as ContextMenuPageViewModel; + if (_model != null) + _model.View = this; + + base.OnDataContextChanged(e); + } + private void InitializeComponent() { AvaloniaXamlLoader.Load(this); diff --git a/samples/ControlCatalog/Pages/MenuPage.xaml.cs b/samples/ControlCatalog/Pages/MenuPage.xaml.cs index 0a77607719..46dbe3dcad 100644 --- a/samples/ControlCatalog/Pages/MenuPage.xaml.cs +++ b/samples/ControlCatalog/Pages/MenuPage.xaml.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Reactive; using System.Threading.Tasks; @@ -21,5 +22,18 @@ namespace ControlCatalog.Pages { AvaloniaXamlLoader.Load(this); } + + private MenuPageViewModel _model; + protected override void OnDataContextChanged(EventArgs e) + { + if (_model != null) + _model.View = null; + _model = DataContext as MenuPageViewModel; + if (_model != null) + _model.View = this; + + base.OnDataContextChanged(e); + } + } } diff --git a/samples/ControlCatalog/ViewModels/ContextMenuPageViewModel.cs b/samples/ControlCatalog/ViewModels/ContextMenuPageViewModel.cs index d34e9af017..5c2f74d2d5 100644 --- a/samples/ControlCatalog/ViewModels/ContextMenuPageViewModel.cs +++ b/samples/ControlCatalog/ViewModels/ContextMenuPageViewModel.cs @@ -2,12 +2,14 @@ using System.Reactive; using System.Threading.Tasks; using Avalonia.Controls; +using Avalonia.VisualTree; using ReactiveUI; namespace ControlCatalog.ViewModels { public class ContextMenuPageViewModel { + public Control View { get; set; } public ContextMenuPageViewModel() { OpenCommand = ReactiveCommand.CreateFromTask(Open); @@ -48,8 +50,11 @@ namespace ControlCatalog.ViewModels public async Task Open() { + var window = View?.GetVisualRoot() as Window; + if (window == null) + return; var dialog = new OpenFileDialog(); - var result = await dialog.ShowAsync(App.Current.MainWindow); + var result = await dialog.ShowAsync(window); if (result != null) { diff --git a/samples/ControlCatalog/ViewModels/MenuPageViewModel.cs b/samples/ControlCatalog/ViewModels/MenuPageViewModel.cs index 88b1bf0b6b..dc9c4a8f49 100644 --- a/samples/ControlCatalog/ViewModels/MenuPageViewModel.cs +++ b/samples/ControlCatalog/ViewModels/MenuPageViewModel.cs @@ -3,12 +3,14 @@ using System.Reactive; using System.Reactive.Linq; using System.Threading.Tasks; using Avalonia.Controls; +using Avalonia.VisualTree; using ReactiveUI; namespace ControlCatalog.ViewModels { public class MenuPageViewModel { + public Control View { get; set; } public MenuPageViewModel() { OpenCommand = ReactiveCommand.CreateFromTask(Open); @@ -65,8 +67,11 @@ namespace ControlCatalog.ViewModels public async Task Open() { + var window = View?.GetVisualRoot() as Window; + if (window == null) + return; var dialog = new OpenFileDialog(); - var result = await dialog.ShowAsync(App.Current.MainWindow); + var result = await dialog.ShowAsync(window); if (result != null) { From 425edab298421d873ba5f2a04f8ff76a8ed45e54 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 22 Jun 2019 00:21:32 +0300 Subject: [PATCH 05/11] Move Screens property to WindowBase since they are in IWindowBaseImpl anyway --- src/Avalonia.Controls/Primitives/PopupRoot.cs | 2 +- src/Avalonia.Controls/Screens.cs | 5 +++-- src/Avalonia.Controls/Window.cs | 3 --- src/Avalonia.Controls/WindowBase.cs | 3 +++ 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Avalonia.Controls/Primitives/PopupRoot.cs b/src/Avalonia.Controls/Primitives/PopupRoot.cs index 90020839d6..d2e8f1ab92 100644 --- a/src/Avalonia.Controls/Primitives/PopupRoot.cs +++ b/src/Avalonia.Controls/Primitives/PopupRoot.cs @@ -80,7 +80,7 @@ namespace Avalonia.Controls.Primitives /// public void SnapInsideScreenEdges() { - var screen = Application.Current.MainWindow?.Screens.ScreenFromPoint(Position); + var screen = (VisualRoot as WindowBase)?.Screens?.ScreenFromPoint(Position); if (screen != null) { diff --git a/src/Avalonia.Controls/Screens.cs b/src/Avalonia.Controls/Screens.cs index 0f0adec790..8a0a0fa728 100644 --- a/src/Avalonia.Controls/Screens.cs +++ b/src/Avalonia.Controls/Screens.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using Avalonia.Platform; using Avalonia.Utilities; @@ -11,7 +12,7 @@ namespace Avalonia.Controls private readonly IScreenImpl _iScreenImpl; public int ScreenCount => _iScreenImpl.ScreenCount; - public IReadOnlyList All => _iScreenImpl?.AllScreens; + public IReadOnlyList All => _iScreenImpl?.AllScreens ?? Array.Empty(); public Screen Primary => All.FirstOrDefault(x => x.Primary); public Screens(IScreenImpl iScreenImpl) diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index 01614ba87b..2265e89af3 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/src/Avalonia.Controls/Window.cs @@ -140,7 +140,6 @@ namespace Avalonia.Controls impl.Closing = HandleClosing; impl.WindowStateChanged = HandleWindowStateChanged; _maxPlatformClientSize = PlatformImpl?.MaxClientSize ?? default(Size); - Screens = new Screens(PlatformImpl?.Screen); } /// @@ -157,8 +156,6 @@ namespace Avalonia.Controls remove { _nameScope.Unregistered -= value; } } - public Screens Screens { get; private set; } - /// /// Gets the platform-specific window implementation. /// diff --git a/src/Avalonia.Controls/WindowBase.cs b/src/Avalonia.Controls/WindowBase.cs index 363af05a0b..40c9fc94d2 100644 --- a/src/Avalonia.Controls/WindowBase.cs +++ b/src/Avalonia.Controls/WindowBase.cs @@ -63,6 +63,7 @@ namespace Avalonia.Controls public WindowBase(IWindowBaseImpl impl, IAvaloniaDependencyResolver dependencyResolver) : base(impl, dependencyResolver) { + Screens = new Screens(PlatformImpl?.Screen); impl.Activated = HandleActivated; impl.Deactivated = HandleDeactivated; impl.PositionChanged = HandlePositionChanged; @@ -108,6 +109,8 @@ namespace Avalonia.Controls impl.Position = value; } } + + public Screens Screens { get; private set; } /// /// Whether an auto-size operation is in progress. From b33601ee9b2c2d669bf58da42f081df7294081af Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 22 Jun 2019 00:30:46 +0300 Subject: [PATCH 06/11] Refactored lifetime control into separate lifetime classes --- samples/ControlCatalog.NetCore/Program.cs | 22 +- samples/ControlCatalog/App.xaml.cs | 11 + src/Avalonia.Controls/AppBuilderBase.cs | 15 +- src/Avalonia.Controls/Application.cs | 200 ++---------------- .../ClassicDesktopStyleApplicationLifetime.cs | 99 +++++++++ ...rolledApplicationLifetimeExitEventArgs.cs} | 11 +- .../IApplicationLifetime.cs | 7 + ...IClassicDesktopStyleApplicationLifetime.cs | 28 +++ .../IControlledApplicationLifetime.cs} | 13 +- .../ISingleViewLifetime.cs | 7 + .../ApplicationLifetimes/StartupEventArgs.cs | 22 ++ .../DesktopApplicationExtensions.cs | 67 ++++++ src/Avalonia.Controls/StartupEventArgs.cs | 36 ---- src/Avalonia.Controls/TopLevel.cs | 20 -- src/Avalonia.Controls/Window.cs | 19 -- src/Avalonia.Controls/WindowCollection.cs | 33 +-- .../Remote/RemoteDesignerEntryPoint.cs | 12 +- .../FramebufferToplevelImpl.cs | 2 +- .../LinuxFramebufferPlatform.cs | 74 +++++-- src/Linux/Avalonia.LinuxFramebuffer/Mice.cs | 12 +- .../ApplicationTests.cs | 120 ----------- .../ContextMenuTests.cs | 4 +- .../DesktopStyleApplicationLifetimeTests.cs | 139 ++++++++++++ .../TopLevelTests.cs | 19 -- .../WindowBaseTests.cs | 6 - .../WindowTests.cs | 2 +- .../Avalonia.UnitTests/UnitTestApplication.cs | 3 +- 27 files changed, 493 insertions(+), 510 deletions(-) create mode 100644 src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs rename src/Avalonia.Controls/{ExitEventArgs.cs => ApplicationLifetimes/ControlledApplicationLifetimeExitEventArgs.cs} (54%) create mode 100644 src/Avalonia.Controls/ApplicationLifetimes/IApplicationLifetime.cs create mode 100644 src/Avalonia.Controls/ApplicationLifetimes/IClassicDesktopStyleApplicationLifetime.cs rename src/Avalonia.Controls/{IApplicationLifecycle.cs => ApplicationLifetimes/IControlledApplicationLifetime.cs} (65%) create mode 100644 src/Avalonia.Controls/ApplicationLifetimes/ISingleViewLifetime.cs create mode 100644 src/Avalonia.Controls/ApplicationLifetimes/StartupEventArgs.cs create mode 100644 src/Avalonia.Controls/DesktopApplicationExtensions.cs delete mode 100644 src/Avalonia.Controls/StartupEventArgs.cs create mode 100644 tests/Avalonia.Controls.UnitTests/DesktopStyleApplicationLifetimeTests.cs diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs index 4027c5cd63..40321496c0 100644 --- a/samples/ControlCatalog.NetCore/Program.cs +++ b/samples/ControlCatalog.NetCore/Program.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Linq; using System.Threading; using Avalonia; +using Avalonia.Controls; using Avalonia.Skia; using Avalonia.ReactiveUI; @@ -11,7 +12,7 @@ namespace ControlCatalog.NetCore static class Program { - static void Main(string[] args) + static int Main(string[] args) { Thread.CurrentThread.TrySetApartmentState(ApartmentState.STA); if (args.Contains("--wait-for-attach")) @@ -25,21 +26,16 @@ namespace ControlCatalog.NetCore } } + var builder = BuildAvaloniaApp(); if (args.Contains("--fbdev")) - AppBuilder.Configure().InitializeWithLinuxFramebuffer(tl => - { - tl.Content = new MainView(); - System.Threading.ThreadPool.QueueUserWorkItem(_ => ConsoleSilencer()); - }); + { + System.Threading.ThreadPool.QueueUserWorkItem(_ => ConsoleSilencer()); + return builder.StartLinuxFramebuffer(args); + } else - BuildAvaloniaApp().Start(AppMain, args); + return builder.StartWithClassicDesktopLifetime(args); } - - static void AppMain(Application app, string[] args) - { - app.Run(new MainWindow()); - } - + /// /// This method is needed for IDE previewer infrastructure /// diff --git a/samples/ControlCatalog/App.xaml.cs b/samples/ControlCatalog/App.xaml.cs index d862749132..b9bce96b2a 100644 --- a/samples/ControlCatalog/App.xaml.cs +++ b/samples/ControlCatalog/App.xaml.cs @@ -1,4 +1,5 @@ using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; namespace ControlCatalog @@ -9,5 +10,15 @@ namespace ControlCatalog { AvaloniaXamlLoader.Load(this); } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktopLifetime) + desktopLifetime.MainWindow = new MainWindow(); + else if (ApplicationLifetime is ISingleViewLifetime singleViewLifetime) + singleViewLifetime.MainView = new MainView(); + + base.OnFrameworkInitializationCompleted(); + } } } diff --git a/src/Avalonia.Controls/AppBuilderBase.cs b/src/Avalonia.Controls/AppBuilderBase.cs index 419064b051..967ebac4ef 100644 --- a/src/Avalonia.Controls/AppBuilderBase.cs +++ b/src/Avalonia.Controls/AppBuilderBase.cs @@ -117,6 +117,7 @@ namespace Avalonia.Controls /// /// The window type. /// A delegate that will be called to create a data context for the window (optional). + [Obsolete("Use either lifetimes or AppMain overload. See see https://github.com/AvaloniaUI/Avalonia/wiki/Application-lifetimes for details")] public void Start(Func dataContextProvider = null) where TMainWindow : Window, new() { @@ -135,6 +136,7 @@ namespace Avalonia.Controls /// The window type. /// Instance of type TMainWindow to use when starting the app /// A delegate that will be called to create a data context for the window (optional). + [Obsolete("Use either lifetimes or AppMain overload. See see https://github.com/AvaloniaUI/Avalonia/wiki/Application-lifetimes for details")] public void Start(TMainWindow mainWindow, Func dataContextProvider = null) where TMainWindow : Window { @@ -148,6 +150,7 @@ namespace Avalonia.Controls public delegate void AppMainDelegate(Application app, string[] args); + [Obsolete("Use either lifetimes or AppMain overload. See see https://github.com/AvaloniaUI/Avalonia/wiki/Application-lifetimes for details")] public void Start() { Setup(); @@ -224,17 +227,6 @@ namespace Avalonia.Controls public TAppBuilder UseAvaloniaModules() => AfterSetup(builder => SetupAvaloniaModules()); - /// - /// Sets the shutdown mode of the application. - /// - /// The shutdown mode. - /// - public TAppBuilder SetShutdownMode(ShutdownMode shutdownMode) - { - Instance.ShutdownMode = shutdownMode; - return Self; - } - protected virtual bool CheckSetup => true; private void SetupAvaloniaModules() @@ -313,6 +305,7 @@ namespace Avalonia.Controls Instance.RegisterServices(); Instance.Initialize(); AfterSetupCallback(Self); + Instance.OnFrameworkInitializationCompleted(); } } } diff --git a/src/Avalonia.Controls/Application.cs b/src/Avalonia.Controls/Application.cs index 9f9fe5eae1..329b757ec4 100644 --- a/src/Avalonia.Controls/Application.cs +++ b/src/Avalonia.Controls/Application.cs @@ -6,6 +6,7 @@ using System.Reactive.Concurrency; using System.Threading; using Avalonia.Animation; using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.Templates; using Avalonia.Input; using Avalonia.Input.Platform; @@ -31,7 +32,7 @@ namespace Avalonia /// method. /// - Tracks the lifetime of the application. /// - public class Application : IApplicationLifecycle, IGlobalDataTemplates, IGlobalStyles, IStyleRoot, IResourceNode + public class Application : IGlobalDataTemplates, IGlobalStyles, IStyleRoot, IResourceNode { /// /// The application-global data templates. @@ -43,8 +44,6 @@ namespace Avalonia private readonly Styler _styler = new Styler(); private Styles _styles; private IResourceDictionary _resources; - private CancellationTokenSource _mainLoopCancellationTokenSource; - private int _exitCode; /// /// Initializes a new instance of the class. @@ -54,12 +53,6 @@ namespace Avalonia Windows = new WindowCollection(this); } - /// - public event EventHandler Startup; - - /// - public event EventHandler Exit; - /// public event EventHandler ResourcesChanged; @@ -167,24 +160,6 @@ namespace Avalonia /// IResourceNode IResourceNode.ResourceParent => null; - /// - /// Gets or sets the . This property indicates whether the application is shutdown explicitly or implicitly. - /// If is set to OnExplicitShutdown the application is only closes if Shutdown is called. - /// The default is OnLastWindowClose - /// - /// - /// The shutdown mode. - /// - public ShutdownMode ShutdownMode { get; set; } - - /// - /// Gets or sets the main window of the application. - /// - /// - /// The main window. - /// - public Window MainWindow { get; set; } - /// /// Gets the open windows of the application. /// @@ -192,172 +167,21 @@ namespace Avalonia /// The windows. /// public WindowCollection Windows { get; } - + /// - /// Gets or sets a value indicating whether this instance is shutting down. + /// Application lifetime, use it for things like setting the main window and exiting the app from code + /// Currently supported lifetimes are: + /// - + /// - + /// - /// - /// - /// true if this instance is shutting down; otherwise, false. - /// - internal bool IsShuttingDown { get; private set; } + public IApplicationLifetime ApplicationLifetime { get; set; } /// /// Initializes the application by loading XAML etc. /// public virtual void Initialize() { } - /// - /// Runs the application's main loop. - /// - /// - /// This will return when the condition is met - /// or was called. - /// - /// The application's exit code that is returned to the operating system on termination. - public int Run() - { - return Run(new CancellationTokenSource()); - } - - /// - /// Runs the application's main loop. - /// - /// - /// This will return when the condition is met - /// or was called. - /// This also returns when is closed. - /// - /// The closable to track. - /// The application's exit code that is returned to the operating system on termination. - public int Run(ICloseable closable) - { - closable.Closed += (s, e) => _mainLoopCancellationTokenSource?.Cancel(); - - return Run(new CancellationTokenSource()); - } - - /// - /// Runs the application's main loop. - /// - /// - /// This will return when the condition is met - /// or was called. - /// - /// The window that is used as - /// when the isn't already set. - /// The application's exit code that is returned to the operating system on termination. - public int Run(Window mainWindow) - { - if (mainWindow == null) - { - throw new ArgumentNullException(nameof(mainWindow)); - } - - if (MainWindow == null) - { - if (!mainWindow.IsVisible) - { - mainWindow.Show(); - } - - MainWindow = mainWindow; - } - - return Run(new CancellationTokenSource()); - } - /// - /// Runs the application's main loop. - /// - /// - /// This will return when the condition is met - /// or was called. - /// This also returns when the is canceled. - /// - /// The application's exit code that is returned to the operating system on termination. - /// The token to track. - public int Run(CancellationToken token) - { - return Run(CancellationTokenSource.CreateLinkedTokenSource(token)); - } - - private int Run(CancellationTokenSource tokenSource) - { - if (IsShuttingDown) - { - throw new InvalidOperationException("Application is shutting down."); - } - - if (_mainLoopCancellationTokenSource != null) - { - throw new InvalidOperationException("Application is already running."); - } - - _mainLoopCancellationTokenSource = tokenSource; - - Dispatcher.UIThread.Post(() => OnStartup(new StartupEventArgs()), DispatcherPriority.Send); - - Dispatcher.UIThread.MainLoop(_mainLoopCancellationTokenSource.Token); - - if (!IsShuttingDown) - { - Shutdown(_exitCode); - } - - return _exitCode; - } - - /// - /// Raises the event. - /// - /// A that contains the event data. - protected virtual void OnStartup(StartupEventArgs e) - { - Startup?.Invoke(this, e); - } - - /// - /// Raises the event. - /// - /// A that contains the event data. - protected virtual void OnExit(ExitEventArgs e) - { - Exit?.Invoke(this, e); - } - - /// - public void Shutdown(int exitCode = 0) - { - if (IsShuttingDown) - { - throw new InvalidOperationException("Application is already shutting down."); - } - - _exitCode = exitCode; - - IsShuttingDown = true; - - Windows.Clear(); - - try - { - var e = new ExitEventArgs { ApplicationExitCode = _exitCode }; - - OnExit(e); - - _exitCode = e.ApplicationExitCode; - } - finally - { - _mainLoopCancellationTokenSource?.Cancel(); - - _mainLoopCancellationTokenSource = null; - - IsShuttingDown = false; - - Environment.ExitCode = _exitCode; - } - } - /// bool IResourceProvider.TryGetResource(object key, out object value) { @@ -383,7 +207,6 @@ namespace Avalonia .Bind().ToConstant(InputManager) .Bind().ToTransient() .Bind().ToConstant(_styler) - .Bind().ToConstant(this) .Bind().ToConstant(AvaloniaScheduler.Instance) .Bind().ToConstant(DragDropDevice.Instance) .Bind().ToTransient(); @@ -394,6 +217,11 @@ namespace Avalonia .GetService()?.Add(clock); } + public virtual void OnFrameworkInitializationCompleted() + { + + } + private void ThisResourcesChanged(object sender, ResourcesChangedEventArgs e) { ResourcesChanged?.Invoke(this, e); diff --git a/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs b/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs new file mode 100644 index 0000000000..d6d5c56537 --- /dev/null +++ b/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs @@ -0,0 +1,99 @@ +using System; +using System.Threading; +using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; + +namespace Avalonia.Controls.ApplicationLifetimes +{ + public class ClassicDesktopStyleApplicationLifetime : IClassicDesktopStyleApplicationLifetime + { + private readonly Application _app; + private int _exitCode; + private CancellationTokenSource _cts; + private bool _isShuttingDown; + + public ClassicDesktopStyleApplicationLifetime(Application app) + { + _app = app; + app.Windows.OnWindowClosed += HandleWindowClosed; + } + + /// + public event EventHandler Startup; + /// + public event EventHandler Exit; + + /// + public ShutdownMode ShutdownMode { get; set; } + + /// + public Window MainWindow { get; set; } + + private void HandleWindowClosed(Window window) + { + if (window == null) + return; + + if (_isShuttingDown) + return; + + if (ShutdownMode == ShutdownMode.OnLastWindowClose && _app.Windows.Count == 0) + Shutdown(); + else if (ShutdownMode == ShutdownMode.OnMainWindowClose && window == MainWindow) + Shutdown(); + } + + + + + public void Shutdown(int exitCode = 0) + { + if (_isShuttingDown) + throw new InvalidOperationException("Application is already shutting down."); + + _exitCode = exitCode; + _isShuttingDown = true; + + try + { + _app.Windows.CloseAll(); + var e = new ControlledApplicationLifetimeExitEventArgs(exitCode); + Exit?.Invoke(this, e); + _exitCode = e.ApplicationExitCode; + } + finally + { + _cts?.Cancel(); + _cts = null; + _isShuttingDown = false; + } + } + + + public int Start(string[] args) + { + Startup?.Invoke(this, new ControlledApplicationLifetimeStartupEventArgs(args)); + _cts = new CancellationTokenSource(); + MainWindow?.Show(); + _app.Run(_cts.Token); + Environment.ExitCode = _exitCode; + return _exitCode; + } + } +} + +namespace Avalonia +{ + public static class ClassicDesktopStyleApplicationLifetimeExtensions + { + public static int StartWithClassicDesktopLifetime( + this T builder, string[] args, ShutdownMode shutdownMode = ShutdownMode.OnLastWindowClose) + where T : AppBuilderBase, new() + { + var lifetime = new ClassicDesktopStyleApplicationLifetime(builder.Instance) {ShutdownMode = shutdownMode}; + builder.Instance.ApplicationLifetime = lifetime; + builder.SetupWithoutStarting(); + return lifetime.Start(args); + } + } +} diff --git a/src/Avalonia.Controls/ExitEventArgs.cs b/src/Avalonia.Controls/ApplicationLifetimes/ControlledApplicationLifetimeExitEventArgs.cs similarity index 54% rename from src/Avalonia.Controls/ExitEventArgs.cs rename to src/Avalonia.Controls/ApplicationLifetimes/ControlledApplicationLifetimeExitEventArgs.cs index c99f7fe047..d4c3b27f7a 100644 --- a/src/Avalonia.Controls/ExitEventArgs.cs +++ b/src/Avalonia.Controls/ApplicationLifetimes/ControlledApplicationLifetimeExitEventArgs.cs @@ -3,13 +3,18 @@ using System; -namespace Avalonia.Controls +namespace Avalonia.Controls.ApplicationLifetimes { /// - /// Contains the arguments for the event. + /// Contains the arguments for the event. /// - public class ExitEventArgs : EventArgs + public class ControlledApplicationLifetimeExitEventArgs : EventArgs { + public ControlledApplicationLifetimeExitEventArgs(int applicationExitCode) + { + ApplicationExitCode = applicationExitCode; + } + /// /// Gets or sets the exit code that an application returns to the operating system when the application exits. /// diff --git a/src/Avalonia.Controls/ApplicationLifetimes/IApplicationLifetime.cs b/src/Avalonia.Controls/ApplicationLifetimes/IApplicationLifetime.cs new file mode 100644 index 0000000000..9860d0cb38 --- /dev/null +++ b/src/Avalonia.Controls/ApplicationLifetimes/IApplicationLifetime.cs @@ -0,0 +1,7 @@ +namespace Avalonia.Controls.ApplicationLifetimes +{ + public interface IApplicationLifetime + { + + } +} diff --git a/src/Avalonia.Controls/ApplicationLifetimes/IClassicDesktopStyleApplicationLifetime.cs b/src/Avalonia.Controls/ApplicationLifetimes/IClassicDesktopStyleApplicationLifetime.cs new file mode 100644 index 0000000000..6d809c6714 --- /dev/null +++ b/src/Avalonia.Controls/ApplicationLifetimes/IClassicDesktopStyleApplicationLifetime.cs @@ -0,0 +1,28 @@ +using System; + +namespace Avalonia.Controls.ApplicationLifetimes +{ + /// + /// Controls application lifetime in classic desktop style + /// + public interface IClassicDesktopStyleApplicationLifetime : IControlledApplicationLifetime + { + /// + /// Gets or sets the . This property indicates whether the application is shutdown explicitly or implicitly. + /// If is set to OnExplicitShutdown the application is only closes if Shutdown is called. + /// The default is OnLastWindowClose + /// + /// + /// The shutdown mode. + /// + ShutdownMode ShutdownMode { get; set; } + + /// + /// Gets or sets the main window of the application. + /// + /// + /// The main window. + /// + Window MainWindow { get; set; } + } +} diff --git a/src/Avalonia.Controls/IApplicationLifecycle.cs b/src/Avalonia.Controls/ApplicationLifetimes/IControlledApplicationLifetime.cs similarity index 65% rename from src/Avalonia.Controls/IApplicationLifecycle.cs rename to src/Avalonia.Controls/ApplicationLifetimes/IControlledApplicationLifetime.cs index a3c6599b20..3f61aeb536 100644 --- a/src/Avalonia.Controls/IApplicationLifecycle.cs +++ b/src/Avalonia.Controls/ApplicationLifetimes/IControlledApplicationLifetime.cs @@ -1,22 +1,19 @@ using System; -namespace Avalonia.Controls +namespace Avalonia.Controls.ApplicationLifetimes { - /// - /// Sends events about the application lifecycle. - /// - public interface IApplicationLifecycle + public interface IControlledApplicationLifetime : IApplicationLifetime { /// /// Sent when the application is starting up. /// - event EventHandler Startup; + event EventHandler Startup; /// /// Sent when the application is exiting. /// - event EventHandler Exit; - + event EventHandler Exit; + /// /// Shuts down the application and sets the exit code that is returned to the operating system when the application exits. /// diff --git a/src/Avalonia.Controls/ApplicationLifetimes/ISingleViewLifetime.cs b/src/Avalonia.Controls/ApplicationLifetimes/ISingleViewLifetime.cs new file mode 100644 index 0000000000..efa42b6d75 --- /dev/null +++ b/src/Avalonia.Controls/ApplicationLifetimes/ISingleViewLifetime.cs @@ -0,0 +1,7 @@ +namespace Avalonia.Controls.ApplicationLifetimes +{ + public interface ISingleViewLifetime : IApplicationLifetime + { + Control MainView { get; set; } + } +} diff --git a/src/Avalonia.Controls/ApplicationLifetimes/StartupEventArgs.cs b/src/Avalonia.Controls/ApplicationLifetimes/StartupEventArgs.cs new file mode 100644 index 0000000000..4c08712707 --- /dev/null +++ b/src/Avalonia.Controls/ApplicationLifetimes/StartupEventArgs.cs @@ -0,0 +1,22 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Avalonia.Controls.ApplicationLifetimes +{ + /// + /// Contains the arguments for the event. + /// + public class ControlledApplicationLifetimeStartupEventArgs : EventArgs + { + public ControlledApplicationLifetimeStartupEventArgs(IEnumerable args) + { + Args = args?.ToArray() ?? Array.Empty(); + } + + public string[] Args { get; } + } +} diff --git a/src/Avalonia.Controls/DesktopApplicationExtensions.cs b/src/Avalonia.Controls/DesktopApplicationExtensions.cs new file mode 100644 index 0000000000..9b81bc94d1 --- /dev/null +++ b/src/Avalonia.Controls/DesktopApplicationExtensions.cs @@ -0,0 +1,67 @@ +using System; +using System.Threading; +using Avalonia.Controls; +using Avalonia.Input; +using Avalonia.Threading; + +namespace Avalonia.Controls +{ + public static class DesktopApplicationExtensions + { + [Obsolete("Running application without a cancellation token and a lifetime is no longer supported, see https://github.com/AvaloniaUI/Avalonia/wiki/Application-lifetimes for details")] + public static void Run(this Application app) => throw new NotSupportedException(); + + /// + /// On desktop-style platforms runs the application's main loop until closable is closed + /// + /// + /// Consider using StartWithDesktopStyleLifetime instead, see https://github.com/AvaloniaUI/Avalonia/wiki/Application-lifetimes for details + /// + public static void Run(this Application app, ICloseable closable) + { + var cts = new CancellationTokenSource(); + closable.Closed += (s, e) => cts.Cancel(); + + app.Run(cts.Token); + } + + /// + /// On desktop-style platforms runs the application's main loop until main window is closed + /// + /// + /// Consider using StartWithDesktopStyleLifetime instead, see https://github.com/AvaloniaUI/Avalonia/wiki/Application-lifetimes for details + /// + public static void Run(this Application app, Window mainWindow) + { + if (mainWindow == null) + { + throw new ArgumentNullException(nameof(mainWindow)); + } + var cts = new CancellationTokenSource(); + mainWindow.Closed += (_, __) => cts.Cancel(); + if (!mainWindow.IsVisible) + { + mainWindow.Show(); + } + app.Run(cts.Token); + } + + /// + /// On desktop-style platforms runs the application's main loop with custom CancellationToken + /// without setting a lifetime. + /// + /// The token to track. + public static void Run(this Application app, CancellationToken token) + { + Dispatcher.UIThread.MainLoop(token); + } + + public static void RunWithMainWindow(this Application app) + where TWindow : Avalonia.Controls.Window, new() + { + var window = new TWindow(); + window.Show(); + app.Run(window); + } + } +} diff --git a/src/Avalonia.Controls/StartupEventArgs.cs b/src/Avalonia.Controls/StartupEventArgs.cs deleted file mode 100644 index 0e12f5c01a..0000000000 --- a/src/Avalonia.Controls/StartupEventArgs.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Avalonia.Controls -{ - /// - /// Contains the arguments for the event. - /// - public class StartupEventArgs : EventArgs - { - private string[] _args; - - /// - /// Gets the command line arguments that were passed to the application. - /// - public IReadOnlyList Args => _args ?? (_args = GetArgs()); - - private static string[] GetArgs() - { - try - { - var args = Environment.GetCommandLineArgs(); - - return args.Length > 1 ? args.Skip(1).ToArray() : new string[0]; - } - catch (NotSupportedException) - { - return new string[0]; - } - } - } -} diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs index 21bd0e4e57..87100ceeb0 100644 --- a/src/Avalonia.Controls/TopLevel.cs +++ b/src/Avalonia.Controls/TopLevel.cs @@ -51,7 +51,6 @@ namespace Avalonia.Controls private readonly IInputManager _inputManager; private readonly IAccessKeyHandler _accessKeyHandler; private readonly IKeyboardNavigationHandler _keyboardNavigationHandler; - private readonly IApplicationLifecycle _applicationLifecycle; private readonly IPlatformRenderInterface _renderInterface; private Size _clientSize; private ILayoutManager _layoutManager; @@ -96,7 +95,6 @@ namespace Avalonia.Controls _accessKeyHandler = TryGetService(dependencyResolver); _inputManager = TryGetService(dependencyResolver); _keyboardNavigationHandler = TryGetService(dependencyResolver); - _applicationLifecycle = TryGetService(dependencyResolver); _renderInterface = TryGetService(dependencyResolver); Renderer = impl.CreateRenderer(this); @@ -125,11 +123,6 @@ namespace Avalonia.Controls x => (x as InputElement)?.GetObservable(CursorProperty) ?? Observable.Empty()) .Switch().Subscribe(cursor => PlatformImpl?.SetCursor(cursor?.PlatformCursor)); - if (_applicationLifecycle != null) - { - _applicationLifecycle.Exit += OnApplicationExiting; - } - if (((IStyleHost)this).StylingParent is IResourceProvider applicationResources) { WeakSubscriptionManager.Subscribe( @@ -281,7 +274,6 @@ namespace Avalonia.Controls Closed?.Invoke(this, EventArgs.Empty); Renderer?.Dispose(); Renderer = null; - _applicationLifecycle.Exit -= OnApplicationExiting; } /// @@ -348,18 +340,6 @@ namespace Avalonia.Controls return result; } - private void OnApplicationExiting(object sender, EventArgs args) - { - HandleApplicationExiting(); - } - - /// - /// Handles the application exiting, either from the last window closing, or a call to . - /// - protected virtual void HandleApplicationExiting() - { - } - /// /// Handles input from . /// diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index 2265e89af3..7ae0380ba0 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/src/Avalonia.Controls/Window.cs @@ -277,12 +277,6 @@ namespace Avalonia.Controls Close(false); } - protected override void HandleApplicationExiting() - { - base.HandleApplicationExiting(); - Close(true); - } - /// /// Closes a dialog window with the specified result. /// @@ -585,16 +579,3 @@ namespace Avalonia.Controls protected virtual void OnClosing(CancelEventArgs e) => Closing?.Invoke(this, e); } } - -namespace Avalonia -{ - public static class WindowApplicationExtensions - { - public static void RunWithMainWindow(this Application app) where TWindow : Avalonia.Controls.Window, new() - { - var window = new TWindow(); - window.Show(); - app.Run(window); - } - } -} diff --git a/src/Avalonia.Controls/WindowCollection.cs b/src/Avalonia.Controls/WindowCollection.cs index 328bb9f147..aa076a1808 100644 --- a/src/Avalonia.Controls/WindowCollection.cs +++ b/src/Avalonia.Controls/WindowCollection.cs @@ -1,6 +1,7 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System; using System.Collections; using System.Collections.Generic; @@ -12,6 +13,7 @@ namespace Avalonia { private readonly Application _application; private readonly List _windows = new List(); + public event Action OnWindowClosed; public WindowCollection(Application application) { @@ -92,7 +94,7 @@ namespace Avalonia /// /// Closes all windows and removes them from the underlying collection. /// - internal void Clear() + public void CloseAll() { while (_windows.Count > 0) { @@ -102,33 +104,8 @@ namespace Avalonia private void OnRemoveWindow(Window window) { - if (window == null) - { - return; - } - - if (_application.IsShuttingDown) - { - return; - } - - switch (_application.ShutdownMode) - { - case ShutdownMode.OnLastWindowClose: - if (Count == 0) - { - _application.Shutdown(); - } - - break; - case ShutdownMode.OnMainWindowClose: - if (window == _application.MainWindow) - { - _application.Shutdown(); - } - - break; - } + if (window != null) + OnWindowClosed?.Invoke(window); } } } diff --git a/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs b/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs index a0e86a53b0..617fbc8005 100644 --- a/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs +++ b/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Net; using System.Reflection; +using System.Threading; using System.Xml; using Avalonia.Controls; using Avalonia.Input; @@ -122,15 +123,6 @@ namespace Avalonia.DesignerSupport.Remote } private const string BuilderMethodName = "BuildAvaloniaApp"; - - class NeverClose : ICloseable - { - public event EventHandler Closed - { - add {} - remove {} - } - } public static void Main(string[] cmdline) { @@ -155,7 +147,7 @@ namespace Avalonia.DesignerSupport.Remote transport.OnException += (t, e) => Die(e.ToString()); Log("Sending StartDesignerSessionMessage"); transport.Send(new StartDesignerSessionMessage {SessionId = args.SessionId}); - app.Run(new NeverClose()); + Dispatcher.UIThread.MainLoop(CancellationToken.None); } diff --git a/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs b/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs index 6a63014e1a..78369a3648 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs @@ -18,7 +18,7 @@ namespace Avalonia.LinuxFramebuffer { _fb = fb; Invalidate(default(Rect)); - var mice = new Mice(ClientSize.Width, ClientSize.Height); + var mice = new Mice(this, ClientSize.Width, ClientSize.Height); mice.Start(); mice.Event += e => Input?.Invoke(e); } diff --git a/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs b/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs index 9ed06c978d..44fd14b3b7 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using System.Threading; using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.Embedding; using Avalonia.Controls.Platform; using Avalonia.Input; @@ -21,7 +22,6 @@ namespace Avalonia.LinuxFramebuffer private static readonly Stopwatch St = Stopwatch.StartNew(); internal static uint Timestamp => (uint)St.ElapsedTicks; public static InternalPlatformThreadingInterface Threading; - public static FramebufferToplevelImpl TopLevel; LinuxFramebufferPlatform(string fbdev = null) { _fb = new LinuxFramebuffer(fbdev); @@ -41,37 +41,73 @@ namespace Avalonia.LinuxFramebuffer .Bind().ToConstant(Threading); } - internal static TopLevel Initialize(T builder, string fbdev = null) where T : AppBuilderBase, new() + internal static LinuxFramebufferLifetime Initialize(T builder, string fbdev = null) where T : AppBuilderBase, new() { var platform = new LinuxFramebufferPlatform(fbdev); - builder.UseSkia().UseWindowingSubsystem(platform.Initialize, "fbdev") - .SetupWithoutStarting(); - var tl = new EmbeddableControlRoot(TopLevel = new FramebufferToplevelImpl(platform._fb)); - tl.Prepare(); - return tl; + builder.UseSkia().UseWindowingSubsystem(platform.Initialize, "fbdev"); + return new LinuxFramebufferLifetime(platform._fb); } } -} -public static class LinuxFramebufferPlatformExtensions -{ - class TokenClosable : ICloseable + class LinuxFramebufferLifetime : IControlledApplicationLifetime, ISingleViewLifetime { - public event EventHandler Closed; + private readonly LinuxFramebuffer _fb; + private TopLevel _topLevel; + private readonly CancellationTokenSource _cts = new CancellationTokenSource(); + public CancellationToken Token => _cts.Token; - public TokenClosable(CancellationToken token) + public LinuxFramebufferLifetime(LinuxFramebuffer fb) + { + _fb = fb; + } + + public Control MainView { - token.Register(() => Dispatcher.UIThread.Post(() => Closed?.Invoke(this, new EventArgs()))); + get => (Control)_topLevel?.Content; + set + { + if (_topLevel == null) + { + + var tl = new EmbeddableControlRoot(new FramebufferToplevelImpl(_fb)); + tl.Prepare(); + _topLevel = tl; + } + _topLevel.Content = value; + } + } + + public int ExitCode { get; private set; } + public event EventHandler Startup; + public event EventHandler Exit; + + public void Start(string[] args) + { + Startup?.Invoke(this, new ControlledApplicationLifetimeStartupEventArgs(args)); + } + + public void Shutdown(int exitCode) + { + ExitCode = exitCode; + var e = new ControlledApplicationLifetimeExitEventArgs(exitCode); + Exit?.Invoke(this, e); + ExitCode = e.ApplicationExitCode; + _cts.Cancel(); } } +} - public static void InitializeWithLinuxFramebuffer(this T builder, Action setup, - CancellationToken stop = default(CancellationToken), string fbdev = null) +public static class LinuxFramebufferPlatformExtensions +{ + public static int StartLinuxFramebuffer(this T builder, string[] args, string fbdev = null) where T : AppBuilderBase, new() { - setup(LinuxFramebufferPlatform.Initialize(builder, fbdev)); - builder.BeforeStartCallback(builder); - builder.Instance.Run(new TokenClosable(stop)); + var lifetime = LinuxFramebufferPlatform.Initialize(builder, fbdev); + builder.Instance.ApplicationLifetime = lifetime; + builder.SetupWithoutStarting(); + lifetime.Start(args); + builder.Instance.Run(lifetime.Token); + return lifetime.ExitCode; } } diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Mice.cs b/src/Linux/Avalonia.LinuxFramebuffer/Mice.cs index b982b98d38..2b82b4f4aa 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/Mice.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/Mice.cs @@ -7,8 +7,9 @@ using Avalonia.Platform; namespace Avalonia.LinuxFramebuffer { - public unsafe class Mice + unsafe class Mice { + private readonly FramebufferToplevelImpl _topLevel; private readonly double _width; private readonly double _height; private double _x; @@ -16,8 +17,9 @@ namespace Avalonia.LinuxFramebuffer public event Action Event; - public Mice(double width, double height) + public Mice(FramebufferToplevelImpl topLevel, double width, double height) { + _topLevel = topLevel; _width = width; _height = height; } @@ -78,7 +80,7 @@ namespace Avalonia.LinuxFramebuffer return; Event?.Invoke(new RawPointerEventArgs(LinuxFramebufferPlatform.MouseDevice, LinuxFramebufferPlatform.Timestamp, - LinuxFramebufferPlatform.TopLevel.InputRoot, RawPointerEventType.Move, new Point(_x, _y), + _topLevel.InputRoot, RawPointerEventType.Move, new Point(_x, _y), InputModifiers.None)); } if (ev.type ==(int) EvType.EV_ABS) @@ -91,7 +93,7 @@ namespace Avalonia.LinuxFramebuffer return; Event?.Invoke(new RawPointerEventArgs(LinuxFramebufferPlatform.MouseDevice, LinuxFramebufferPlatform.Timestamp, - LinuxFramebufferPlatform.TopLevel.InputRoot, RawPointerEventType.Move, new Point(_x, _y), + _topLevel.InputRoot, RawPointerEventType.Move, new Point(_x, _y), InputModifiers.None)); } if (ev.type == (short) EvType.EV_KEY) @@ -108,7 +110,7 @@ namespace Avalonia.LinuxFramebuffer Event?.Invoke(new RawPointerEventArgs(LinuxFramebufferPlatform.MouseDevice, LinuxFramebufferPlatform.Timestamp, - LinuxFramebufferPlatform.TopLevel.InputRoot, type.Value, new Point(_x, _y), default(InputModifiers))); + _topLevel.InputRoot, type.Value, new Point(_x, _y), default(InputModifiers))); } } } diff --git a/tests/Avalonia.Controls.UnitTests/ApplicationTests.cs b/tests/Avalonia.Controls.UnitTests/ApplicationTests.cs index b7d752dfe3..9e31cab421 100644 --- a/tests/Avalonia.Controls.UnitTests/ApplicationTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ApplicationTests.cs @@ -11,113 +11,6 @@ namespace Avalonia.Controls.UnitTests { public class ApplicationTests { - [Fact] - public void Should_Exit_After_MainWindow_Closed() - { - using (UnitTestApplication.Start(TestServices.StyledWindow)) - { - Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose; - - var hasExit = false; - - Application.Current.Exit += (s, e) => hasExit = true; - - var mainWindow = new Window(); - - mainWindow.Show(); - - Application.Current.MainWindow = mainWindow; - - var window = new Window(); - - window.Show(); - - mainWindow.Close(); - - Assert.True(hasExit); - } - } - - [Fact] - public void Should_Exit_After_Last_Window_Closed() - { - using (UnitTestApplication.Start(TestServices.StyledWindow)) - { - Application.Current.ShutdownMode = ShutdownMode.OnLastWindowClose; - - var hasExit = false; - - Application.Current.Exit += (s, e) => hasExit = true; - - var windowA = new Window(); - - windowA.Show(); - - var windowB = new Window(); - - windowB.Show(); - - windowA.Close(); - - Assert.False(hasExit); - - windowB.Close(); - - Assert.True(hasExit); - } - } - - [Fact] - public void Should_Only_Exit_On_Explicit_Exit() - { - using (UnitTestApplication.Start(TestServices.StyledWindow)) - { - Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown; - - var hasExit = false; - - Application.Current.Exit += (s, e) => hasExit = true; - - var windowA = new Window(); - - windowA.Show(); - - var windowB = new Window(); - - windowB.Show(); - - windowA.Close(); - - Assert.False(hasExit); - - windowB.Close(); - - Assert.False(hasExit); - - Application.Current.Shutdown(); - - Assert.True(hasExit); - } - } - - [Fact] - public void Should_Close_All_Remaining_Open_Windows_After_Explicit_Exit_Call() - { - using (UnitTestApplication.Start(TestServices.StyledWindow)) - { - var windows = new List { new Window(), new Window(), new Window(), new Window() }; - - foreach (var window in windows) - { - window.Show(); - } - - Application.Current.Shutdown(); - - Assert.Empty(Application.Current.Windows); - } - } - [Fact] public void Throws_ArgumentNullException_On_Run_If_MainWindow_Is_Null() { @@ -142,18 +35,5 @@ namespace Avalonia.Controls.UnitTests Assert.True(raised); } } - - [Fact] - public void Should_Set_ExitCode_After_Shutdown() - { - using (UnitTestApplication.Start(TestServices.MockThreadingInterface)) - { - Application.Current.Shutdown(1337); - - var exitCode = Application.Current.Run(); - - Assert.Equal(1337, exitCode); - } - } } } diff --git a/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs b/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs index 067c66969f..6482fcb4da 100644 --- a/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs @@ -59,9 +59,7 @@ namespace Avalonia.Controls.UnitTests }; var window = new Window { Content = target }; - - Avalonia.Application.Current.MainWindow = window; - + _mouse.Click(target, MouseButton.Right); Assert.True(sut.IsOpen); diff --git a/tests/Avalonia.Controls.UnitTests/DesktopStyleApplicationLifetimeTests.cs b/tests/Avalonia.Controls.UnitTests/DesktopStyleApplicationLifetimeTests.cs new file mode 100644 index 0000000000..ee27d6493b --- /dev/null +++ b/tests/Avalonia.Controls.UnitTests/DesktopStyleApplicationLifetimeTests.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Threading; +using Avalonia.UnitTests; +using Xunit; + +namespace Avalonia.Controls.UnitTests +{ + + public class DesktopStyleApplicationLifetimeTests + { + [Fact] + public void Should_Set_ExitCode_After_Shutdown() + { + using (UnitTestApplication.Start(TestServices.MockThreadingInterface)) + { + var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current); + Dispatcher.UIThread.InvokeAsync(() => lifetime.Shutdown(1337)); + lifetime.Shutdown(1337); + + var exitCode = lifetime.Start(Array.Empty()); + + Assert.Equal(1337, exitCode); + } + } + + + [Fact] + public void Should_Close_All_Remaining_Open_Windows_After_Explicit_Exit_Call() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var windows = new List { new Window(), new Window(), new Window(), new Window() }; + + foreach (var window in windows) + { + window.Show(); + } + new ClassicDesktopStyleApplicationLifetime(Application.Current).Shutdown(); + + Assert.Empty(Application.Current.Windows); + } + } + + [Fact] + public void Should_Only_Exit_On_Explicit_Exit() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current); + lifetime.ShutdownMode = ShutdownMode.OnExplicitShutdown; + + var hasExit = false; + + lifetime.Exit += (s, e) => hasExit = true; + + var windowA = new Window(); + + windowA.Show(); + + var windowB = new Window(); + + windowB.Show(); + + windowA.Close(); + + Assert.False(hasExit); + + windowB.Close(); + + Assert.False(hasExit); + + lifetime.Shutdown(); + + Assert.True(hasExit); + } + } + + [Fact] + public void Should_Exit_After_MainWindow_Closed() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current); + lifetime.ShutdownMode = ShutdownMode.OnMainWindowClose; + + var hasExit = false; + + lifetime.Exit += (s, e) => hasExit = true; + + var mainWindow = new Window(); + + mainWindow.Show(); + + lifetime.MainWindow = mainWindow; + + var window = new Window(); + + window.Show(); + + mainWindow.Close(); + + Assert.True(hasExit); + } + } + + [Fact] + public void Should_Exit_After_Last_Window_Closed() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current); + lifetime.ShutdownMode = ShutdownMode.OnLastWindowClose; + + var hasExit = false; + + lifetime.Exit += (s, e) => hasExit = true; + + var windowA = new Window(); + + windowA.Show(); + + var windowB = new Window(); + + windowB.Show(); + + windowA.Close(); + + Assert.False(hasExit); + + windowB.Close(); + + Assert.True(hasExit); + } + } + } + +} diff --git a/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs b/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs index aa99d31cff..f112289460 100644 --- a/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TopLevelTests.cs @@ -207,19 +207,6 @@ namespace Avalonia.Controls.UnitTests } } - [Fact] - public void Exiting_Application_Notifies_Top_Level() - { - using (UnitTestApplication.Start(TestServices.StyledWindow)) - { - var impl = new Mock(); - impl.SetupAllProperties(); - var target = new TestTopLevel(impl.Object); - UnitTestApplication.Current.Shutdown(); - Assert.True(target.IsClosed); - } - } - [Fact] public void Adding_Resource_To_Application_Should_Raise_ResourcesChanged() { @@ -259,12 +246,6 @@ namespace Avalonia.Controls.UnitTests } protected override ILayoutManager CreateLayoutManager() => _layoutManager; - - protected override void HandleApplicationExiting() - { - base.HandleApplicationExiting(); - IsClosed = true; - } } } } diff --git a/tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs b/tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs index 6d00409ae0..12d29f2e5b 100644 --- a/tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs +++ b/tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs @@ -276,12 +276,6 @@ namespace Avalonia.Controls.UnitTests : base(impl) { } - - protected override void HandleApplicationExiting() - { - base.HandleApplicationExiting(); - IsClosed = true; - } } } } diff --git a/tests/Avalonia.Controls.UnitTests/WindowTests.cs b/tests/Avalonia.Controls.UnitTests/WindowTests.cs index ee416c4cb0..35f60e92cd 100644 --- a/tests/Avalonia.Controls.UnitTests/WindowTests.cs +++ b/tests/Avalonia.Controls.UnitTests/WindowTests.cs @@ -425,7 +425,7 @@ namespace Avalonia.Controls.UnitTests { // HACK: We really need a decent way to have "statics" that can be scoped to // AvaloniaLocator scopes. - Application.Current.Windows.Clear(); + Application.Current.Windows.CloseAll(); } } } diff --git a/tests/Avalonia.UnitTests/UnitTestApplication.cs b/tests/Avalonia.UnitTests/UnitTestApplication.cs index 3578471397..a516facb92 100644 --- a/tests/Avalonia.UnitTests/UnitTestApplication.cs +++ b/tests/Avalonia.UnitTests/UnitTestApplication.cs @@ -66,8 +66,7 @@ namespace Avalonia.UnitTests .Bind().ToConstant(Services.StandardCursorFactory) .Bind().ToConstant(Services.Styler) .Bind().ToConstant(Services.WindowingPlatform) - .Bind().ToSingleton() - .Bind().ToConstant(this); + .Bind().ToSingleton(); var styles = Services.Theme?.Invoke(); if (styles != null) From c161d4e07c6e758f186383f409b846429d620c5a Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 22 Jun 2019 01:30:37 +0300 Subject: [PATCH 07/11] AppBuilderBase cleanup --- src/Avalonia.Controls/AppBuilderBase.cs | 38 ------------------------- 1 file changed, 38 deletions(-) diff --git a/src/Avalonia.Controls/AppBuilderBase.cs b/src/Avalonia.Controls/AppBuilderBase.cs index 967ebac4ef..0f0b55e9e8 100644 --- a/src/Avalonia.Controls/AppBuilderBase.cs +++ b/src/Avalonia.Controls/AppBuilderBase.cs @@ -57,10 +57,6 @@ namespace Avalonia.Controls /// public Action AfterSetupCallback { get; private set; } = builder => { }; - /// - /// Gets or sets a method to call before Start is called on the . - /// - public Action BeforeStartCallback { get; private set; } = builder => { }; protected AppBuilderBase(IRuntimePlatform platform, Action platformServices) { @@ -95,17 +91,6 @@ namespace Avalonia.Controls protected TAppBuilder Self => (TAppBuilder)this; - /// - /// Registers a callback to call before Start is called on the . - /// - /// The callback. - /// An instance. - public TAppBuilder BeforeStarting(Action callback) - { - BeforeStartCallback = (Action)Delegate.Combine(BeforeStartCallback, callback); - return Self; - } - public TAppBuilder AfterSetup(Action callback) { AfterSetupCallback = (Action)Delegate.Combine(AfterSetupCallback, callback); @@ -121,47 +106,24 @@ namespace Avalonia.Controls public void Start(Func dataContextProvider = null) where TMainWindow : Window, new() { - Setup(); - BeforeStartCallback(Self); - var window = new TMainWindow(); if (dataContextProvider != null) window.DataContext = dataContextProvider(); Instance.Run(window); } - /// - /// Starts the application with the provided instance of . - /// - /// The window type. - /// Instance of type TMainWindow to use when starting the app - /// A delegate that will be called to create a data context for the window (optional). - [Obsolete("Use either lifetimes or AppMain overload. See see https://github.com/AvaloniaUI/Avalonia/wiki/Application-lifetimes for details")] - public void Start(TMainWindow mainWindow, Func dataContextProvider = null) - where TMainWindow : Window - { - Setup(); - BeforeStartCallback(Self); - - if (dataContextProvider != null) - mainWindow.DataContext = dataContextProvider(); - Instance.Run(mainWindow); - } - public delegate void AppMainDelegate(Application app, string[] args); [Obsolete("Use either lifetimes or AppMain overload. See see https://github.com/AvaloniaUI/Avalonia/wiki/Application-lifetimes for details")] public void Start() { Setup(); - BeforeStartCallback(Self); Instance.Run(); } public void Start(AppMainDelegate main, string[] args) { Setup(); - BeforeStartCallback(Self); main(Instance, args); } From 3655b6eea17293dbcf3a4f574c19d21da7b74a85 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 22 Jun 2019 11:34:01 +0300 Subject: [PATCH 08/11] Move Application.Windows to IClassicDesktopStyleApplicationLifetime --- src/Avalonia.Controls/Application.cs | 16 --- .../ClassicDesktopStyleApplicationLifetime.cs | 42 ++++++- ...IClassicDesktopStyleApplicationLifetime.cs | 3 + src/Avalonia.Controls/Window.cs | 41 +++---- src/Avalonia.Controls/WindowCollection.cs | 111 ------------------ .../DesktopStyleApplicationLifetimeTests.cs | 88 ++++++++++++-- .../WindowTests.cs | 76 ------------ 7 files changed, 140 insertions(+), 237 deletions(-) delete mode 100644 src/Avalonia.Controls/WindowCollection.cs diff --git a/src/Avalonia.Controls/Application.cs b/src/Avalonia.Controls/Application.cs index 329b757ec4..acd9534d14 100644 --- a/src/Avalonia.Controls/Application.cs +++ b/src/Avalonia.Controls/Application.cs @@ -45,14 +45,6 @@ namespace Avalonia private Styles _styles; private IResourceDictionary _resources; - /// - /// Initializes a new instance of the class. - /// - public Application() - { - Windows = new WindowCollection(this); - } - /// public event EventHandler ResourcesChanged; @@ -159,14 +151,6 @@ namespace Avalonia /// IResourceNode IResourceNode.ResourceParent => null; - - /// - /// Gets the open windows of the application. - /// - /// - /// The windows. - /// - public WindowCollection Windows { get; } /// /// Application lifetime, use it for things like setting the main window and exiting the app from code diff --git a/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs b/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs index d6d5c56537..abca7a64ee 100644 --- a/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs +++ b/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs @@ -1,21 +1,46 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Interactivity; namespace Avalonia.Controls.ApplicationLifetimes { - public class ClassicDesktopStyleApplicationLifetime : IClassicDesktopStyleApplicationLifetime + public class ClassicDesktopStyleApplicationLifetime : IClassicDesktopStyleApplicationLifetime, IDisposable { private readonly Application _app; private int _exitCode; private CancellationTokenSource _cts; private bool _isShuttingDown; + private HashSet _windows = new HashSet(); + + private static ClassicDesktopStyleApplicationLifetime _activeLifetime; + static ClassicDesktopStyleApplicationLifetime() + { + Window.WindowOpenedEvent.AddClassHandler(typeof(Window), OnWindowOpened); + Window.WindowClosedEvent.AddClassHandler(typeof(Window), WindowClosedEvent); + } + + private static void WindowClosedEvent(object sender, RoutedEventArgs e) + { + _activeLifetime?._windows.Remove((Window)sender); + _activeLifetime?.HandleWindowClosed((Window)sender); + } + + private static void OnWindowOpened(object sender, RoutedEventArgs e) + { + _activeLifetime?._windows.Add((Window)sender); + } public ClassicDesktopStyleApplicationLifetime(Application app) { + if (_activeLifetime != null) + throw new InvalidOperationException( + "Can not have multiple active ClassicDesktopStyleApplicationLifetime instances and the previously created one was not disposed"); _app = app; - app.Windows.OnWindowClosed += HandleWindowClosed; + _activeLifetime = this; } /// @@ -29,6 +54,8 @@ namespace Avalonia.Controls.ApplicationLifetimes /// public Window MainWindow { get; set; } + public IReadOnlyList Windows => _windows.ToList(); + private void HandleWindowClosed(Window window) { if (window == null) @@ -37,7 +64,7 @@ namespace Avalonia.Controls.ApplicationLifetimes if (_isShuttingDown) return; - if (ShutdownMode == ShutdownMode.OnLastWindowClose && _app.Windows.Count == 0) + if (ShutdownMode == ShutdownMode.OnLastWindowClose && _windows.Count == 0) Shutdown(); else if (ShutdownMode == ShutdownMode.OnMainWindowClose && window == MainWindow) Shutdown(); @@ -56,7 +83,8 @@ namespace Avalonia.Controls.ApplicationLifetimes try { - _app.Windows.CloseAll(); + foreach (var w in Windows) + w.Close(); var e = new ControlledApplicationLifetimeExitEventArgs(exitCode); Exit?.Invoke(this, e); _exitCode = e.ApplicationExitCode; @@ -79,6 +107,12 @@ namespace Avalonia.Controls.ApplicationLifetimes Environment.ExitCode = _exitCode; return _exitCode; } + + public void Dispose() + { + if (_activeLifetime == this) + _activeLifetime = null; + } } } diff --git a/src/Avalonia.Controls/ApplicationLifetimes/IClassicDesktopStyleApplicationLifetime.cs b/src/Avalonia.Controls/ApplicationLifetimes/IClassicDesktopStyleApplicationLifetime.cs index 6d809c6714..a1006d907b 100644 --- a/src/Avalonia.Controls/ApplicationLifetimes/IClassicDesktopStyleApplicationLifetime.cs +++ b/src/Avalonia.Controls/ApplicationLifetimes/IClassicDesktopStyleApplicationLifetime.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace Avalonia.Controls.ApplicationLifetimes { @@ -24,5 +25,7 @@ namespace Avalonia.Controls.ApplicationLifetimes /// The main window. /// Window MainWindow { get; set; } + + IReadOnlyList Windows { get; } } } diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index 7ae0380ba0..5c117f508b 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/src/Avalonia.Controls/Window.cs @@ -14,6 +14,7 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using System.ComponentModel; +using Avalonia.Interactivity; namespace Avalonia.Controls { @@ -97,6 +98,20 @@ namespace Avalonia.Controls public static readonly StyledProperty CanResizeProperty = AvaloniaProperty.Register(nameof(CanResize), true); + /// + /// Routed event that can be used for global tracking of window destruction + /// + public static readonly RoutedEvent WindowClosedEvent = + RoutedEvent.Register("WindowClosed", RoutingStrategies.Direct); + + /// + /// Routed event that can be used for global tracking of opening windows + /// + public static readonly RoutedEvent WindowOpenedEvent = + RoutedEvent.Register("WindowOpened", RoutingStrategies.Direct); + + + private readonly NameScope _nameScope = new NameScope(); private object _dialogResult; private readonly Size _maxPlatformClientSize; @@ -249,26 +264,6 @@ namespace Avalonia.Controls /// public event EventHandler Closing; - private static void AddWindow(Window window) - { - if (Application.Current == null) - { - return; - } - - Application.Current.Windows.Add(window); - } - - private static void RemoveWindow(Window window) - { - if (Application.Current == null) - { - return; - } - - Application.Current.Windows.Remove(window); - } - /// /// Closes the window. /// @@ -376,7 +371,7 @@ namespace Avalonia.Controls return; } - AddWindow(this); + this.RaiseEvent(new RoutedEventArgs(WindowOpenedEvent)); EnsureInitialized(); IsVisible = true; @@ -438,7 +433,7 @@ namespace Avalonia.Controls throw new InvalidOperationException("The window is already being shown."); } - AddWindow(this); + RaiseEvent(new RoutedEventArgs(WindowOpenedEvent)); EnsureInitialized(); IsVisible = true; @@ -551,7 +546,7 @@ namespace Avalonia.Controls protected override void HandleClosed() { - RemoveWindow(this); + RaiseEvent(new RoutedEventArgs(WindowClosedEvent)); base.HandleClosed(); } diff --git a/src/Avalonia.Controls/WindowCollection.cs b/src/Avalonia.Controls/WindowCollection.cs deleted file mode 100644 index aa076a1808..0000000000 --- a/src/Avalonia.Controls/WindowCollection.cs +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; -using System.Collections; -using System.Collections.Generic; - -using Avalonia.Controls; - -namespace Avalonia -{ - public class WindowCollection : IReadOnlyList - { - private readonly Application _application; - private readonly List _windows = new List(); - public event Action OnWindowClosed; - - public WindowCollection(Application application) - { - _application = application; - } - - /// - /// - /// Gets the number of elements in the collection. - /// - public int Count => _windows.Count; - - /// - /// - /// Gets the at the specified index. - /// - /// - /// The . - /// - /// The index. - /// - public Window this[int index] => _windows[index]; - - /// - /// - /// Returns an enumerator that iterates through the collection. - /// - /// - /// An enumerator that can be used to iterate through the collection. - /// - public IEnumerator GetEnumerator() - { - return _windows.GetEnumerator(); - } - - /// - /// - /// Returns an enumerator that iterates through a collection. - /// - /// - /// An object that can be used to iterate through the collection. - /// - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - /// - /// Adds the specified window. - /// - /// The window. - internal void Add(Window window) - { - if (window == null) - { - return; - } - - _windows.Add(window); - } - - /// - /// Removes the specified window. - /// - /// The window. - internal void Remove(Window window) - { - if (window == null) - { - return; - } - - _windows.Remove(window); - - OnRemoveWindow(window); - } - - /// - /// Closes all windows and removes them from the underlying collection. - /// - public void CloseAll() - { - while (_windows.Count > 0) - { - _windows[0].Close(true); - } - } - - private void OnRemoveWindow(Window window) - { - if (window != null) - OnWindowClosed?.Invoke(window); - } - } -} diff --git a/tests/Avalonia.Controls.UnitTests/DesktopStyleApplicationLifetimeTests.cs b/tests/Avalonia.Controls.UnitTests/DesktopStyleApplicationLifetimeTests.cs index ee27d6493b..74523d4193 100644 --- a/tests/Avalonia.Controls.UnitTests/DesktopStyleApplicationLifetimeTests.cs +++ b/tests/Avalonia.Controls.UnitTests/DesktopStyleApplicationLifetimeTests.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Platform; using Avalonia.Threading; using Avalonia.UnitTests; +using Moq; using Xunit; namespace Avalonia.Controls.UnitTests @@ -14,9 +16,8 @@ namespace Avalonia.Controls.UnitTests public void Should_Set_ExitCode_After_Shutdown() { using (UnitTestApplication.Start(TestServices.MockThreadingInterface)) + using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) { - var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current); - Dispatcher.UIThread.InvokeAsync(() => lifetime.Shutdown(1337)); lifetime.Shutdown(1337); var exitCode = lifetime.Start(Array.Empty()); @@ -30,6 +31,7 @@ namespace Avalonia.Controls.UnitTests public void Should_Close_All_Remaining_Open_Windows_After_Explicit_Exit_Call() { using (UnitTestApplication.Start(TestServices.StyledWindow)) + using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) { var windows = new List { new Window(), new Window(), new Window(), new Window() }; @@ -37,9 +39,10 @@ namespace Avalonia.Controls.UnitTests { window.Show(); } - new ClassicDesktopStyleApplicationLifetime(Application.Current).Shutdown(); + Assert.Equal(4, lifetime.Windows.Count); + lifetime.Shutdown(); - Assert.Empty(Application.Current.Windows); + Assert.Empty(lifetime.Windows); } } @@ -47,8 +50,8 @@ namespace Avalonia.Controls.UnitTests public void Should_Only_Exit_On_Explicit_Exit() { using (UnitTestApplication.Start(TestServices.StyledWindow)) + using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) { - var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current); lifetime.ShutdownMode = ShutdownMode.OnExplicitShutdown; var hasExit = false; @@ -81,8 +84,8 @@ namespace Avalonia.Controls.UnitTests public void Should_Exit_After_MainWindow_Closed() { using (UnitTestApplication.Start(TestServices.StyledWindow)) + using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) { - var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current); lifetime.ShutdownMode = ShutdownMode.OnMainWindowClose; var hasExit = false; @@ -109,8 +112,8 @@ namespace Avalonia.Controls.UnitTests public void Should_Exit_After_Last_Window_Closed() { using (UnitTestApplication.Start(TestServices.StyledWindow)) + using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) { - var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current); lifetime.ShutdownMode = ShutdownMode.OnLastWindowClose; var hasExit = false; @@ -134,6 +137,77 @@ namespace Avalonia.Controls.UnitTests Assert.True(hasExit); } } + + [Fact] + public void Show_Should_Add_Window_To_OpenWindows() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) + { + var window = new Window(); + + window.Show(); + + Assert.Equal(new[] { window }, lifetime.Windows); + } + } + + [Fact] + public void Window_Should_Be_Added_To_OpenWindows_Only_Once() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) + { + var window = new Window(); + + window.Show(); + window.Show(); + window.IsVisible = true; + + Assert.Equal(new[] { window }, lifetime.Windows); + + window.Close(); + } + } + + [Fact] + public void Close_Should_Remove_Window_From_OpenWindows() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) + { + var window = new Window(); + + window.Show(); + Assert.Equal(1, lifetime.Windows.Count); + window.Close(); + + Assert.Empty(lifetime.Windows); + } + } + + [Fact] + public void Impl_Closing_Should_Remove_Window_From_OpenWindows() + { + var windowImpl = new Mock(); + windowImpl.SetupProperty(x => x.Closed); + windowImpl.Setup(x => x.Scaling).Returns(1); + + var services = TestServices.StyledWindow.With( + windowingPlatform: new MockWindowingPlatform(() => windowImpl.Object)); + + using (UnitTestApplication.Start(services)) + using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) + { + var window = new Window(); + + window.Show(); + Assert.Equal(1, lifetime.Windows.Count); + windowImpl.Object.Closed(); + + Assert.Empty(lifetime.Windows); + } + } } } diff --git a/tests/Avalonia.Controls.UnitTests/WindowTests.cs b/tests/Avalonia.Controls.UnitTests/WindowTests.cs index 35f60e92cd..f4d9a91d0c 100644 --- a/tests/Avalonia.Controls.UnitTests/WindowTests.cs +++ b/tests/Avalonia.Controls.UnitTests/WindowTests.cs @@ -121,75 +121,6 @@ namespace Avalonia.Controls.UnitTests } } - [Fact] - public void Show_Should_Add_Window_To_OpenWindows() - { - using (UnitTestApplication.Start(TestServices.StyledWindow)) - { - ClearOpenWindows(); - var window = new Window(); - - window.Show(); - - Assert.Equal(new[] { window }, Application.Current.Windows); - } - } - - [Fact] - public void Window_Should_Be_Added_To_OpenWindows_Only_Once() - { - using (UnitTestApplication.Start(TestServices.StyledWindow)) - { - ClearOpenWindows(); - var window = new Window(); - - window.Show(); - window.Show(); - window.IsVisible = true; - - Assert.Equal(new[] { window }, Application.Current.Windows); - - window.Close(); - } - } - - [Fact] - public void Close_Should_Remove_Window_From_OpenWindows() - { - using (UnitTestApplication.Start(TestServices.StyledWindow)) - { - ClearOpenWindows(); - var window = new Window(); - - window.Show(); - window.Close(); - - Assert.Empty(Application.Current.Windows); - } - } - - [Fact] - public void Impl_Closing_Should_Remove_Window_From_OpenWindows() - { - var windowImpl = new Mock(); - windowImpl.SetupProperty(x => x.Closed); - windowImpl.Setup(x => x.Scaling).Returns(1); - - var services = TestServices.StyledWindow.With( - windowingPlatform: new MockWindowingPlatform(() => windowImpl.Object)); - - using (UnitTestApplication.Start(services)) - { - ClearOpenWindows(); - var window = new Window(); - - window.Show(); - windowImpl.Object.Closed(); - - Assert.Empty(Application.Current.Windows); - } - } - [Fact] public void Closing_Should_Only_Be_Invoked_Once() { @@ -420,12 +351,5 @@ namespace Avalonia.Controls.UnitTests x.Scaling == 1 && x.CreateRenderer(It.IsAny()) == renderer.Object); } - - private void ClearOpenWindows() - { - // HACK: We really need a decent way to have "statics" that can be scoped to - // AvaloniaLocator scopes. - Application.Current.Windows.CloseAll(); - } } } From 3e071fc3662170857645f624b8c6b5c84f4a9515 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 22 Jun 2019 11:34:40 +0300 Subject: [PATCH 09/11] Naming --- samples/ControlCatalog/App.xaml.cs | 2 +- src/Avalonia.Controls/Application.cs | 2 +- ...ISingleViewLifetime.cs => ISingleViewApplicationLifetime.cs} | 2 +- src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/Avalonia.Controls/ApplicationLifetimes/{ISingleViewLifetime.cs => ISingleViewApplicationLifetime.cs} (58%) diff --git a/samples/ControlCatalog/App.xaml.cs b/samples/ControlCatalog/App.xaml.cs index b9bce96b2a..07c42c60c4 100644 --- a/samples/ControlCatalog/App.xaml.cs +++ b/samples/ControlCatalog/App.xaml.cs @@ -15,7 +15,7 @@ namespace ControlCatalog { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktopLifetime) desktopLifetime.MainWindow = new MainWindow(); - else if (ApplicationLifetime is ISingleViewLifetime singleViewLifetime) + else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewLifetime) singleViewLifetime.MainView = new MainView(); base.OnFrameworkInitializationCompleted(); diff --git a/src/Avalonia.Controls/Application.cs b/src/Avalonia.Controls/Application.cs index acd9534d14..382106de65 100644 --- a/src/Avalonia.Controls/Application.cs +++ b/src/Avalonia.Controls/Application.cs @@ -156,7 +156,7 @@ namespace Avalonia /// Application lifetime, use it for things like setting the main window and exiting the app from code /// Currently supported lifetimes are: /// - - /// - + /// - /// - /// public IApplicationLifetime ApplicationLifetime { get; set; } diff --git a/src/Avalonia.Controls/ApplicationLifetimes/ISingleViewLifetime.cs b/src/Avalonia.Controls/ApplicationLifetimes/ISingleViewApplicationLifetime.cs similarity index 58% rename from src/Avalonia.Controls/ApplicationLifetimes/ISingleViewLifetime.cs rename to src/Avalonia.Controls/ApplicationLifetimes/ISingleViewApplicationLifetime.cs index efa42b6d75..eb451f51af 100644 --- a/src/Avalonia.Controls/ApplicationLifetimes/ISingleViewLifetime.cs +++ b/src/Avalonia.Controls/ApplicationLifetimes/ISingleViewApplicationLifetime.cs @@ -1,6 +1,6 @@ namespace Avalonia.Controls.ApplicationLifetimes { - public interface ISingleViewLifetime : IApplicationLifetime + public interface ISingleViewApplicationLifetime : IApplicationLifetime { Control MainView { get; set; } } diff --git a/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs b/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs index 44fd14b3b7..396942c8dd 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs @@ -49,7 +49,7 @@ namespace Avalonia.LinuxFramebuffer } } - class LinuxFramebufferLifetime : IControlledApplicationLifetime, ISingleViewLifetime + class LinuxFramebufferLifetime : IControlledApplicationLifetime, ISingleViewApplicationLifetime { private readonly LinuxFramebuffer _fb; private TopLevel _topLevel; From 998ef86a68855c09b10a7a299dcda4ef2a772414 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 22 Jun 2019 22:42:03 +0300 Subject: [PATCH 10/11] =?UTF-8?q?[GTK3]=20F=C3=9CER?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Avalonia.sln | 29 - src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj | 11 - src/Gtk/Avalonia.Gtk3/ClipboardImpl.cs | 51 - src/Gtk/Avalonia.Gtk3/CursorFactory.cs | 84 -- src/Gtk/Avalonia.Gtk3/FramebufferManager.cs | 62 - src/Gtk/Avalonia.Gtk3/GdkCursor.cs | 86 -- src/Gtk/Avalonia.Gtk3/GdkKey.cs | 1341 ----------------- .../Gtk3ForeignX11SystemDialog.cs | 115 -- src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs | 168 --- src/Gtk/Avalonia.Gtk3/GtkScreen.cs | 24 - .../Avalonia.Gtk3/IDeferredRenderOperation.cs | 9 - .../Avalonia.Gtk3/ImageSurfaceFramebuffer.cs | 144 -- src/Gtk/Avalonia.Gtk3/Interop/CairoSurface.cs | 20 - src/Gtk/Avalonia.Gtk3/Interop/GException.cs | 30 - src/Gtk/Avalonia.Gtk3/Interop/GObject.cs | 87 -- src/Gtk/Avalonia.Gtk3/Interop/GlibPriority.cs | 46 - src/Gtk/Avalonia.Gtk3/Interop/GlibTimeout.cs | 58 - .../ICustomGtk3NativeLibraryResolver.cs | 12 - .../Interop/ManagedCairoSurface.cs | 37 - src/Gtk/Avalonia.Gtk3/Interop/Native.cs | 790 ---------- .../Avalonia.Gtk3/Interop/NativeException.cs | 20 - src/Gtk/Avalonia.Gtk3/Interop/Pixbuf.cs | 65 - src/Gtk/Avalonia.Gtk3/Interop/Resolver.cs | 156 -- src/Gtk/Avalonia.Gtk3/Interop/Signal.cs | 47 - src/Gtk/Avalonia.Gtk3/KeyTransform.cs | 230 --- src/Gtk/Avalonia.Gtk3/PlatformIconLoader.cs | 20 - src/Gtk/Avalonia.Gtk3/PopupImpl.cs | 19 - .../Avalonia.Gtk3/Properties/AssemblyInfo.cs | 10 - src/Gtk/Avalonia.Gtk3/README.md | 8 - src/Gtk/Avalonia.Gtk3/ScreenImpl.cs | 56 - src/Gtk/Avalonia.Gtk3/SystemDialogs.cs | 110 -- src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs | 527 ------- src/Gtk/Avalonia.Gtk3/WindowImpl.cs | 102 -- src/Gtk/Avalonia.Gtk3/X11.cs | 78 - src/Gtk/Avalonia.Gtk3/X11Framebuffer.cs | 55 - 35 files changed, 4707 deletions(-) delete mode 100644 src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj delete mode 100644 src/Gtk/Avalonia.Gtk3/ClipboardImpl.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/CursorFactory.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/FramebufferManager.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/GdkCursor.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/GdkKey.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/Gtk3ForeignX11SystemDialog.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/GtkScreen.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/IDeferredRenderOperation.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/ImageSurfaceFramebuffer.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/Interop/CairoSurface.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/Interop/GException.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/Interop/GObject.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/Interop/GlibPriority.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/Interop/GlibTimeout.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/Interop/ICustomGtk3NativeLibraryResolver.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/Interop/ManagedCairoSurface.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/Interop/Native.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/Interop/NativeException.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/Interop/Pixbuf.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/Interop/Resolver.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/Interop/Signal.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/KeyTransform.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/PlatformIconLoader.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/PopupImpl.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/Properties/AssemblyInfo.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/README.md delete mode 100644 src/Gtk/Avalonia.Gtk3/ScreenImpl.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/SystemDialogs.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/WindowImpl.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/X11.cs delete mode 100644 src/Gtk/Avalonia.Gtk3/X11Framebuffer.cs diff --git a/Avalonia.sln b/Avalonia.sln index f86c18ba1e..ac678ba9ba 100644 --- a/Avalonia.sln +++ b/Avalonia.sln @@ -63,8 +63,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{A689DE src\Shared\SharedAssemblyInfo.cs = src\Shared\SharedAssemblyInfo.cs EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Gtk", "Gtk", "{B9894058-278A-46B5-B6ED-AD613FCC03B3}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI", "src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj", "{6417B24E-49C2-4985-8DB2-3AB9D898EC91}" EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "PlatformSupport", "src\Shared\PlatformSupport\PlatformSupport.shproj", "{E4D9629C-F168-4224-3F51-A5E482FFBC42}" @@ -123,8 +121,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Android", "s EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia", "src\Skia\Avalonia.Skia\Avalonia.Skia.csproj", "{7D2D3083-71DD-4CC9-8907-39A0D86FB322}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Gtk3", "src\Gtk\Avalonia.Gtk3\Avalonia.Gtk3.csproj", "{BB1F7BB5-6AD4-4776-94D9-C09D0A972658}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControlCatalog.NetCore", "samples\ControlCatalog.NetCore\ControlCatalog.NetCore.csproj", "{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1-27F5-4255-9AFC-04ABFD11683A}" @@ -1318,30 +1314,6 @@ Global {7D2D3083-71DD-4CC9-8907-39A0D86FB322}.Release|iPhone.Build.0 = Release|Any CPU {7D2D3083-71DD-4CC9-8907-39A0D86FB322}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU {7D2D3083-71DD-4CC9-8907-39A0D86FB322}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.AppStore|Any CPU.Build.0 = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.AppStore|iPhone.ActiveCfg = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.AppStore|iPhone.Build.0 = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Debug|iPhone.Build.0 = Debug|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Release|Any CPU.Build.0 = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Release|iPhone.ActiveCfg = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Release|iPhone.Build.0 = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}.Release|iPhoneSimulator.Build.0 = Release|Any CPU {39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU {39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU {39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU @@ -1911,7 +1883,6 @@ Global {F1FDC5B0-4654-416F-AE69-E3E9BBD87801} = {9B9E3891-2366-4253-A952-D08BCEB71098} {29132311-1848-4FD6-AE0C-4FF841151BD3} = {9B9E3891-2366-4253-A952-D08BCEB71098} {7D2D3083-71DD-4CC9-8907-39A0D86FB322} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E} - {BB1F7BB5-6AD4-4776-94D9-C09D0A972658} = {B9894058-278A-46B5-B6ED-AD613FCC03B3} {39D7B147-1A5B-47C2-9D01-21FB7C47C4B3} = {9B9E3891-2366-4253-A952-D08BCEB71098} {854568D5-13D1-4B4F-B50D-534DC7EFD3C9} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B} {638580B0-7910-40EF-B674-DCB34DA308CD} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9} diff --git a/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj b/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj deleted file mode 100644 index 95443a364e..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - netstandard2.0 - true - $(DefineConstants);GTK3_PINVOKE - Avalonia.Gtk3 - - - - - diff --git a/src/Gtk/Avalonia.Gtk3/ClipboardImpl.cs b/src/Gtk/Avalonia.Gtk3/ClipboardImpl.cs deleted file mode 100644 index a860673732..0000000000 --- a/src/Gtk/Avalonia.Gtk3/ClipboardImpl.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Threading.Tasks; -using Avalonia.Gtk3.Interop; -using Avalonia.Input.Platform; -using Avalonia.Platform.Interop; - -namespace Avalonia.Gtk3 -{ - class ClipboardImpl : IClipboard - { - - IntPtr GetClipboard() => Native.GtkClipboardGetForDisplay(Native.GdkGetDefaultDisplay(), IntPtr.Zero); - - static void OnText(IntPtr clipboard, IntPtr utf8string, IntPtr userdata) - { - var handle = GCHandle.FromIntPtr(userdata); - - ((TaskCompletionSource) handle.Target) - .TrySetResult(Utf8Buffer.StringFromPtr(utf8string)); - handle.Free(); - } - - private static readonly Native.D.GtkClipboardTextReceivedFunc OnTextDelegate = OnText; - - static ClipboardImpl() - { - GCHandle.Alloc(OnTextDelegate); - } - - public Task GetTextAsync() - { - var tcs = new TaskCompletionSource(); - Native.GtkClipboardRequestText(GetClipboard(), OnTextDelegate, GCHandle.ToIntPtr(GCHandle.Alloc(tcs))); - return tcs.Task; - } - - public Task SetTextAsync(string text) - { - using (var buf = new Utf8Buffer(text)) - Native.GtkClipboardSetText(GetClipboard(), buf, buf.ByteLen); - return Task.FromResult(0); - } - - public Task ClearAsync() - { - Native.GtkClipboardRequestClear(GetClipboard()); - return Task.FromResult(0); - } - } -} diff --git a/src/Gtk/Avalonia.Gtk3/CursorFactory.cs b/src/Gtk/Avalonia.Gtk3/CursorFactory.cs deleted file mode 100644 index 95fa3ba9e3..0000000000 --- a/src/Gtk/Avalonia.Gtk3/CursorFactory.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.Collections.Generic; -using Avalonia.Gtk3.Interop; -using Avalonia.Input; -using Avalonia.Platform; -using Avalonia.Platform.Interop; -using CursorType = Avalonia.Gtk3.GdkCursorType; -namespace Avalonia.Gtk3 -{ - class CursorFactory : IStandardCursorFactory - { - private static readonly Dictionary CursorTypeMapping = new Dictionary - - { - {StandardCursorType.None, CursorType.Blank}, - {StandardCursorType.AppStarting, CursorType.Watch}, - {StandardCursorType.Arrow, CursorType.LeftPtr}, - {StandardCursorType.Cross, CursorType.Cross}, - {StandardCursorType.Hand, CursorType.Hand1}, - {StandardCursorType.Ibeam, CursorType.Xterm}, - {StandardCursorType.No, "gtk-cancel"}, - {StandardCursorType.SizeAll, CursorType.Sizing}, - //{ StandardCursorType.SizeNorthEastSouthWest, 32643 }, - {StandardCursorType.SizeNorthSouth, CursorType.SbVDoubleArrow}, - //{ StandardCursorType.SizeNorthWestSouthEast, 32642 }, - {StandardCursorType.SizeWestEast, CursorType.SbHDoubleArrow}, - {StandardCursorType.UpArrow, CursorType.BasedArrowUp}, - {StandardCursorType.Wait, CursorType.Watch}, - {StandardCursorType.Help, "gtk-help"}, - {StandardCursorType.TopSide, CursorType.TopSide}, - {StandardCursorType.BottomSize, CursorType.BottomSide}, - {StandardCursorType.LeftSide, CursorType.LeftSide}, - {StandardCursorType.RightSide, CursorType.RightSide}, - {StandardCursorType.TopLeftCorner, CursorType.TopLeftCorner}, - {StandardCursorType.TopRightCorner, CursorType.TopRightCorner}, - {StandardCursorType.BottomLeftCorner, CursorType.BottomLeftCorner}, - {StandardCursorType.BottomRightCorner, CursorType.BottomRightCorner}, - {StandardCursorType.DragCopy, CursorType.CenterPtr}, - {StandardCursorType.DragMove, CursorType.Fleur}, - {StandardCursorType.DragLink, CursorType.Cross}, - }; - - private static readonly Dictionary Cache = - new Dictionary(); - - private IntPtr GetCursor(object desc) - { - IntPtr rv; - var name = desc as string; - if (name != null) - { - var theme = Native.GtkIconThemeGetDefault(); - IntPtr icon, error; - using (var u = new Utf8Buffer(name)) - icon = Native.GtkIconThemeLoadIcon(theme, u, 32, 0, out error); - rv = icon == IntPtr.Zero - ? Native.GdkCursorNew(GdkCursorType.XCursor) - : Native.GdkCursorNewFromPixbuf(Native.GdkGetDefaultDisplay(), icon, 0, 0); - } - else - { - rv = Native.GdkCursorNew((CursorType)desc); - } - - - return rv; - } - - public IPlatformHandle GetCursor(StandardCursorType cursorType) - { - IPlatformHandle rv; - if (!Cache.TryGetValue(cursorType, out rv)) - { - Cache[cursorType] = - rv = - new PlatformHandle( - GetCursor(CursorTypeMapping[cursorType]), - "GTKCURSOR"); - } - - return rv; - } - } -} diff --git a/src/Gtk/Avalonia.Gtk3/FramebufferManager.cs b/src/Gtk/Avalonia.Gtk3/FramebufferManager.cs deleted file mode 100644 index e3bbe19978..0000000000 --- a/src/Gtk/Avalonia.Gtk3/FramebufferManager.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using Avalonia.Controls.Platform.Surfaces; -using Avalonia.Platform; -using Avalonia.Threading; - -namespace Avalonia.Gtk3 -{ - class FramebufferManager : IFramebufferPlatformSurface, IDisposable - { - private readonly WindowBaseImpl _window; - public FramebufferManager(WindowBaseImpl window) - { - _window = window; - } - - public void Dispose() - { - // - } - - public ILockedFramebuffer Lock() - { - // This method may be called from non-UI thread, don't touch anything that calls back to GTK/GDK - var s = _window.ClientSize; - var width = Math.Max(1, (int) s.Width); - var height = Math.Max(1, (int) s.Height); - - - if (!Dispatcher.UIThread.CheckAccess() && Gtk3Platform.DisplayClassName.ToLower().Contains("x11")) - { - var x11 = LockX11Framebuffer(width, height); - if (x11 != null) - return x11; - } - - - return new ImageSurfaceFramebuffer(_window, width, height, _window.LastKnownScaleFactor); - } - - private static int X11ErrorHandler(IntPtr d, ref X11.XErrorEvent e) - { - return 0; - } - - private static X11.XErrorHandler X11ErrorHandlerDelegate = X11ErrorHandler; - - private static IntPtr X11Display; - private ILockedFramebuffer LockX11Framebuffer(int width, int height) - { - if (!_window.GdkWindowHandle.HasValue) - return null; - if (X11Display == IntPtr.Zero) - { - X11Display = X11.XOpenDisplay(IntPtr.Zero); - if (X11Display == IntPtr.Zero) - return null; - X11.XSetErrorHandler(X11ErrorHandlerDelegate); - } - return new X11Framebuffer(X11Display, _window.GdkWindowHandle.Value, width, height, _window.LastKnownScaleFactor); - } - } -} diff --git a/src/Gtk/Avalonia.Gtk3/GdkCursor.cs b/src/Gtk/Avalonia.Gtk3/GdkCursor.cs deleted file mode 100644 index aa0f8cde0d..0000000000 --- a/src/Gtk/Avalonia.Gtk3/GdkCursor.cs +++ /dev/null @@ -1,86 +0,0 @@ -namespace Avalonia.Gtk3 -{ - enum GdkCursorType - { - Blank = -2, - CursorIsPixmap = -1, - XCursor = 0, - Arrow = 2, - BasedArrowDown = 4, - BasedArrowUp = 6, - Boat = 8, - Bogosity = 10, - BottomLeftCorner = 12, - BottomRightCorner = 14, - BottomSide = 16, - BottomTee = 18, - BoxSpiral = 20, - CenterPtr = 22, - Circle = 24, - Clock = 26, - CoffeeMug = 28, - Cross = 30, - CrossReverse = 32, - Crosshair = 34, - DiamondCross = 36, - Dot = 38, - Dotbox = 40, - DoubleArrow = 42, - DraftLarge = 44, - DraftSmall = 46, - DrapedBox = 48, - Exchange = 50, - Fleur = 52, - Gobbler = 54, - Gumby = 56, - Hand1 = 58, - Hand2 = 60, - Heart = 62, - Icon = 64, - IronCross = 66, - LeftPtr = 68, - LeftSide = 70, - LeftTee = 72, - Leftbutton = 74, - LlAngle = 76, - LrAngle = 78, - Man = 80, - Middlebutton = 82, - Mouse = 84, - Pencil = 86, - Pirate = 88, - Plus = 90, - QuestionArrow = 92, - RightPtr = 94, - RightSide = 96, - RightTee = 98, - Rightbutton = 100, - RtlLogo = 102, - Sailboat = 104, - SbDownArrow = 106, - SbHDoubleArrow = 108, - SbLeftArrow = 110, - SbRightArrow = 112, - SbUpArrow = 114, - SbVDoubleArrow = 116, - Shuttle = 118, - Sizing = 120, - Spider = 122, - Spraycan = 124, - Star = 126, - Target = 128, - Tcross = 130, - TopLeftArrow = 132, - TopLeftCorner = 134, - TopRightCorner = 136, - TopSide = 138, - TopTee = 140, - Trek = 142, - UlAngle = 144, - Umbrella = 146, - UrAngle = 148, - Watch = 150, - Xterm = 152, - LastCursor = 153, - } -} diff --git a/src/Gtk/Avalonia.Gtk3/GdkKey.cs b/src/Gtk/Avalonia.Gtk3/GdkKey.cs deleted file mode 100644 index 7aa165a1da..0000000000 --- a/src/Gtk/Avalonia.Gtk3/GdkKey.cs +++ /dev/null @@ -1,1341 +0,0 @@ -namespace Avalonia.Gtk3 -{ - enum GdkKey - { - space = 32, - exclam = 33, - quotedbl = 34, - numbersign = 35, - dollar = 36, - percent = 37, - ampersand = 38, - apostrophe = 39, - quoteright = 39, - parenleft = 40, - parenright = 41, - asterisk = 42, - plus = 43, - comma = 44, - minus = 45, - period = 46, - slash = 47, - Key_0 = 48, - Key_1 = 49, - Key_2 = 50, - Key_3 = 51, - Key_4 = 52, - Key_5 = 53, - Key_6 = 54, - Key_7 = 55, - Key_8 = 56, - Key_9 = 57, - colon = 58, - semicolon = 59, - less = 60, - equal = 61, - greater = 62, - question = 63, - at = 64, - A = 65, - B = 66, - C = 67, - D = 68, - E = 69, - F = 70, - G = 71, - H = 72, - I = 73, - J = 74, - K = 75, - L = 76, - M = 77, - N = 78, - O = 79, - P = 80, - Q = 81, - R = 82, - S = 83, - T = 84, - U = 85, - V = 86, - W = 87, - X = 88, - Y = 89, - Z = 90, - bracketleft = 91, - backslash = 92, - bracketright = 93, - asciicircum = 94, - underscore = 95, - grave = 96, - quoteleft = 96, - a = 97, - b = 98, - c = 99, - d = 100, - e = 101, - f = 102, - g = 103, - h = 104, - i = 105, - j = 106, - k = 107, - l = 108, - m = 109, - n = 110, - o = 111, - p = 112, - q = 113, - r = 114, - s = 115, - t = 116, - u = 117, - v = 118, - w = 119, - x = 120, - y = 121, - z = 122, - braceleft = 123, - bar = 124, - braceright = 125, - asciitilde = 126, - nobreakspace = 160, - exclamdown = 161, - cent = 162, - sterling = 163, - currency = 164, - yen = 165, - brokenbar = 166, - section = 167, - diaeresis = 168, - copyright = 169, - ordfeminine = 170, - guillemotleft = 171, - notsign = 172, - hyphen = 173, - registered = 174, - macron = 175, - degree = 176, - plusminus = 177, - twosuperior = 178, - threesuperior = 179, - acute = 180, - mu = 181, - paragraph = 182, - periodcentered = 183, - cedilla = 184, - onesuperior = 185, - masculine = 186, - guillemotright = 187, - onequarter = 188, - onehalf = 189, - threequarters = 190, - questiondown = 191, - Agrave = 192, - Aacute = 193, - Acircumflex = 194, - Atilde = 195, - Adiaeresis = 196, - Aring = 197, - AE = 198, - Ccedilla = 199, - Egrave = 200, - Eacute = 201, - Ecircumflex = 202, - Ediaeresis = 203, - Igrave = 204, - Iacute = 205, - Icircumflex = 206, - Idiaeresis = 207, - ETH = 208, - Eth = 208, - Ntilde = 209, - Ograve = 210, - Oacute = 211, - Ocircumflex = 212, - Otilde = 213, - Odiaeresis = 214, - multiply = 215, - Ooblique = 216, - Ugrave = 217, - Uacute = 218, - Ucircumflex = 219, - Udiaeresis = 220, - Yacute = 221, - THORN = 222, - Thorn = 222, - ssharp = 223, - agrave = 224, - aacute = 225, - acircumflex = 226, - atilde = 227, - adiaeresis = 228, - aring = 229, - ae = 230, - ccedilla = 231, - egrave = 232, - eacute = 233, - ecircumflex = 234, - ediaeresis = 235, - igrave = 236, - iacute = 237, - icircumflex = 238, - idiaeresis = 239, - eth = 240, - ntilde = 241, - ograve = 242, - oacute = 243, - ocircumflex = 244, - otilde = 245, - odiaeresis = 246, - division = 247, - oslash = 248, - ugrave = 249, - uacute = 250, - ucircumflex = 251, - udiaeresis = 252, - yacute = 253, - thorn = 254, - ydiaeresis = 255, - Aogonek = 417, - breve = 418, - Lstroke = 419, - Lcaron = 421, - Sacute = 422, - Scaron = 425, - Scedilla = 426, - Tcaron = 427, - Zacute = 428, - Zcaron = 430, - Zabovedot = 431, - aogonek = 433, - ogonek = 434, - lstroke = 435, - lcaron = 437, - sacute = 438, - caron = 439, - scaron = 441, - scedilla = 442, - tcaron = 443, - zacute = 444, - doubleacute = 445, - zcaron = 446, - zabovedot = 447, - Racute = 448, - Abreve = 451, - Lacute = 453, - Cacute = 454, - Ccaron = 456, - Eogonek = 458, - Ecaron = 460, - Dcaron = 463, - Dstroke = 464, - Nacute = 465, - Ncaron = 466, - Odoubleacute = 469, - Rcaron = 472, - Uring = 473, - Udoubleacute = 475, - Tcedilla = 478, - racute = 480, - abreve = 483, - lacute = 485, - cacute = 486, - ccaron = 488, - eogonek = 490, - ecaron = 492, - dcaron = 495, - dstroke = 496, - nacute = 497, - ncaron = 498, - odoubleacute = 501, - rcaron = 504, - uring = 505, - udoubleacute = 507, - tcedilla = 510, - abovedot = 511, - Hstroke = 673, - Hcircumflex = 678, - Iabovedot = 681, - Gbreve = 683, - Jcircumflex = 684, - hstroke = 689, - hcircumflex = 694, - idotless = 697, - gbreve = 699, - jcircumflex = 700, - Cabovedot = 709, - Ccircumflex = 710, - Gabovedot = 725, - Gcircumflex = 728, - Ubreve = 733, - Scircumflex = 734, - cabovedot = 741, - ccircumflex = 742, - gabovedot = 757, - gcircumflex = 760, - ubreve = 765, - scircumflex = 766, - kappa = 930, - kra = 930, - Rcedilla = 931, - Itilde = 933, - Lcedilla = 934, - Emacron = 938, - Gcedilla = 939, - Tslash = 940, - rcedilla = 947, - itilde = 949, - lcedilla = 950, - emacron = 954, - gcedilla = 955, - tslash = 956, - ENG = 957, - eng = 959, - Amacron = 960, - Iogonek = 967, - Eabovedot = 972, - Imacron = 975, - Ncedilla = 977, - Omacron = 978, - Kcedilla = 979, - Uogonek = 985, - Utilde = 989, - Umacron = 990, - amacron = 992, - iogonek = 999, - eabovedot = 1004, - imacron = 1007, - ncedilla = 1009, - omacron = 1010, - kcedilla = 1011, - uogonek = 1017, - utilde = 1021, - umacron = 1022, - overline = 1150, - kana_fullstop = 1185, - kana_openingbracket = 1186, - kana_closingbracket = 1187, - kana_comma = 1188, - kana_conjunctive = 1189, - kana_middledot = 1189, - kana_WO = 1190, - kana_a = 1191, - kana_i = 1192, - kana_u = 1193, - kana_e = 1194, - kana_o = 1195, - kana_ya = 1196, - kana_yu = 1197, - kana_yo = 1198, - kana_tsu = 1199, - kana_tu = 1199, - prolongedsound = 1200, - kana_A = 1201, - kana_I = 1202, - kana_U = 1203, - kana_E = 1204, - kana_O = 1205, - kana_KA = 1206, - kana_KI = 1207, - kana_KU = 1208, - kana_KE = 1209, - kana_KO = 1210, - kana_SA = 1211, - kana_SHI = 1212, - kana_SU = 1213, - kana_SE = 1214, - kana_SO = 1215, - kana_TA = 1216, - kana_CHI = 1217, - kana_TI = 1217, - kana_TSU = 1218, - kana_TU = 1218, - kana_TE = 1219, - kana_TO = 1220, - kana_NA = 1221, - kana_NI = 1222, - kana_NU = 1223, - kana_NE = 1224, - kana_NO = 1225, - kana_HA = 1226, - kana_HI = 1227, - kana_FU = 1228, - kana_HU = 1228, - kana_HE = 1229, - kana_HO = 1230, - kana_MA = 1231, - kana_MI = 1232, - kana_MU = 1233, - kana_ME = 1234, - kana_MO = 1235, - kana_YA = 1236, - kana_YU = 1237, - kana_YO = 1238, - kana_RA = 1239, - kana_RI = 1240, - kana_RU = 1241, - kana_RE = 1242, - kana_RO = 1243, - kana_WA = 1244, - kana_N = 1245, - voicedsound = 1246, - semivoicedsound = 1247, - Arabic_comma = 1452, - Arabic_semicolon = 1467, - Arabic_question_mark = 1471, - Arabic_hamza = 1473, - Arabic_maddaonalef = 1474, - Arabic_hamzaonalef = 1475, - Arabic_hamzaonwaw = 1476, - Arabic_hamzaunderalef = 1477, - Arabic_hamzaonyeh = 1478, - Arabic_alef = 1479, - Arabic_beh = 1480, - Arabic_tehmarbuta = 1481, - Arabic_teh = 1482, - Arabic_theh = 1483, - Arabic_jeem = 1484, - Arabic_hah = 1485, - Arabic_khah = 1486, - Arabic_dal = 1487, - Arabic_thal = 1488, - Arabic_ra = 1489, - Arabic_zain = 1490, - Arabic_seen = 1491, - Arabic_sheen = 1492, - Arabic_sad = 1493, - Arabic_dad = 1494, - Arabic_tah = 1495, - Arabic_zah = 1496, - Arabic_ain = 1497, - Arabic_ghain = 1498, - Arabic_tatweel = 1504, - Arabic_feh = 1505, - Arabic_qaf = 1506, - Arabic_kaf = 1507, - Arabic_lam = 1508, - Arabic_meem = 1509, - Arabic_noon = 1510, - Arabic_ha = 1511, - Arabic_heh = 1511, - Arabic_waw = 1512, - Arabic_alefmaksura = 1513, - Arabic_yeh = 1514, - Arabic_fathatan = 1515, - Arabic_dammatan = 1516, - Arabic_kasratan = 1517, - Arabic_fatha = 1518, - Arabic_damma = 1519, - Arabic_kasra = 1520, - Arabic_shadda = 1521, - Arabic_sukun = 1522, - Serbian_dje = 1697, - Macedonia_gje = 1698, - Cyrillic_io = 1699, - Ukrainian_ie = 1700, - Ukranian_je = 1700, - Macedonia_dse = 1701, - Ukrainian_i = 1702, - Ukranian_i = 1702, - Ukrainian_yi = 1703, - Ukranian_yi = 1703, - Cyrillic_je = 1704, - Serbian_je = 1704, - Cyrillic_lje = 1705, - Serbian_lje = 1705, - Cyrillic_nje = 1706, - Serbian_nje = 1706, - Serbian_tshe = 1707, - Macedonia_kje = 1708, - Byelorussian_shortu = 1710, - Cyrillic_dzhe = 1711, - Serbian_dze = 1711, - numerosign = 1712, - Serbian_DJE = 1713, - Macedonia_GJE = 1714, - Cyrillic_IO = 1715, - Ukrainian_IE = 1716, - Ukranian_JE = 1716, - Macedonia_DSE = 1717, - Ukrainian_I = 1718, - Ukranian_I = 1718, - Ukrainian_YI = 1719, - Ukranian_YI = 1719, - Cyrillic_JE = 1720, - Serbian_JE = 1720, - Cyrillic_LJE = 1721, - Serbian_LJE = 1721, - Cyrillic_NJE = 1722, - Serbian_NJE = 1722, - Serbian_TSHE = 1723, - Macedonia_KJE = 1724, - Byelorussian_SHORTU = 1726, - Cyrillic_DZHE = 1727, - Serbian_DZE = 1727, - Cyrillic_yu = 1728, - Cyrillic_a = 1729, - Cyrillic_be = 1730, - Cyrillic_tse = 1731, - Cyrillic_de = 1732, - Cyrillic_ie = 1733, - Cyrillic_ef = 1734, - Cyrillic_ghe = 1735, - Cyrillic_ha = 1736, - Cyrillic_i = 1737, - Cyrillic_shorti = 1738, - Cyrillic_ka = 1739, - Cyrillic_el = 1740, - Cyrillic_em = 1741, - Cyrillic_en = 1742, - Cyrillic_o = 1743, - Cyrillic_pe = 1744, - Cyrillic_ya = 1745, - Cyrillic_er = 1746, - Cyrillic_es = 1747, - Cyrillic_te = 1748, - Cyrillic_u = 1749, - Cyrillic_zhe = 1750, - Cyrillic_ve = 1751, - Cyrillic_softsign = 1752, - Cyrillic_yeru = 1753, - Cyrillic_ze = 1754, - Cyrillic_sha = 1755, - Cyrillic_e = 1756, - Cyrillic_shcha = 1757, - Cyrillic_che = 1758, - Cyrillic_hardsign = 1759, - Cyrillic_YU = 1760, - Cyrillic_A = 1761, - Cyrillic_BE = 1762, - Cyrillic_TSE = 1763, - Cyrillic_DE = 1764, - Cyrillic_IE = 1765, - Cyrillic_EF = 1766, - Cyrillic_GHE = 1767, - Cyrillic_HA = 1768, - Cyrillic_I = 1769, - Cyrillic_SHORTI = 1770, - Cyrillic_KA = 1771, - Cyrillic_EL = 1772, - Cyrillic_EM = 1773, - Cyrillic_EN = 1774, - Cyrillic_O = 1775, - Cyrillic_PE = 1776, - Cyrillic_YA = 1777, - Cyrillic_ER = 1778, - Cyrillic_ES = 1779, - Cyrillic_TE = 1780, - Cyrillic_U = 1781, - Cyrillic_ZHE = 1782, - Cyrillic_VE = 1783, - Cyrillic_SOFTSIGN = 1784, - Cyrillic_YERU = 1785, - Cyrillic_ZE = 1786, - Cyrillic_SHA = 1787, - Cyrillic_E = 1788, - Cyrillic_SHCHA = 1789, - Cyrillic_CHE = 1790, - Cyrillic_HARDSIGN = 1791, - Greek_ALPHAaccent = 1953, - Greek_EPSILONaccent = 1954, - Greek_ETAaccent = 1955, - Greek_IOTAaccent = 1956, - Greek_IOTAdiaeresis = 1957, - Greek_OMICRONaccent = 1959, - Greek_UPSILONaccent = 1960, - Greek_UPSILONdieresis = 1961, - Greek_OMEGAaccent = 1963, - Greek_accentdieresis = 1966, - Greek_horizbar = 1967, - Greek_alphaaccent = 1969, - Greek_epsilonaccent = 1970, - Greek_etaaccent = 1971, - Greek_iotaaccent = 1972, - Greek_iotadieresis = 1973, - Greek_iotaaccentdieresis = 1974, - Greek_omicronaccent = 1975, - Greek_upsilonaccent = 1976, - Greek_upsilondieresis = 1977, - Greek_upsilonaccentdieresis = 1978, - Greek_omegaaccent = 1979, - Greek_ALPHA = 1985, - Greek_BETA = 1986, - Greek_GAMMA = 1987, - Greek_DELTA = 1988, - Greek_EPSILON = 1989, - Greek_ZETA = 1990, - Greek_ETA = 1991, - Greek_THETA = 1992, - Greek_IOTA = 1993, - Greek_KAPPA = 1994, - Greek_LAMBDA = 1995, - Greek_LAMDA = 1995, - Greek_MU = 1996, - Greek_NU = 1997, - Greek_XI = 1998, - Greek_OMICRON = 1999, - Greek_PI = 2000, - Greek_RHO = 2001, - Greek_SIGMA = 2002, - Greek_TAU = 2004, - Greek_UPSILON = 2005, - Greek_PHI = 2006, - Greek_CHI = 2007, - Greek_PSI = 2008, - Greek_OMEGA = 2009, - Greek_alpha = 2017, - Greek_beta = 2018, - Greek_gamma = 2019, - Greek_delta = 2020, - Greek_epsilon = 2021, - Greek_zeta = 2022, - Greek_eta = 2023, - Greek_theta = 2024, - Greek_iota = 2025, - Greek_kappa = 2026, - Greek_lambda = 2027, - Greek_lamda = 2027, - Greek_mu = 2028, - Greek_nu = 2029, - Greek_xi = 2030, - Greek_omicron = 2031, - Greek_pi = 2032, - Greek_rho = 2033, - Greek_sigma = 2034, - Greek_finalsmallsigma = 2035, - Greek_tau = 2036, - Greek_upsilon = 2037, - Greek_phi = 2038, - Greek_chi = 2039, - Greek_psi = 2040, - Greek_omega = 2041, - leftradical = 2209, - topleftradical = 2210, - horizconnector = 2211, - topintegral = 2212, - botintegral = 2213, - vertconnector = 2214, - topleftsqbracket = 2215, - botleftsqbracket = 2216, - toprightsqbracket = 2217, - botrightsqbracket = 2218, - topleftparens = 2219, - botleftparens = 2220, - toprightparens = 2221, - botrightparens = 2222, - leftmiddlecurlybrace = 2223, - rightmiddlecurlybrace = 2224, - topleftsummation = 2225, - botleftsummation = 2226, - topvertsummationconnector = 2227, - botvertsummationconnector = 2228, - toprightsummation = 2229, - botrightsummation = 2230, - rightmiddlesummation = 2231, - lessthanequal = 2236, - notequal = 2237, - greaterthanequal = 2238, - integral = 2239, - therefore = 2240, - variation = 2241, - infinity = 2242, - nabla = 2245, - approximate = 2248, - similarequal = 2249, - ifonlyif = 2253, - implies = 2254, - identical = 2255, - radical = 2262, - includedin = 2266, - includes = 2267, - intersection = 2268, - union = 2269, - logicaland = 2270, - logicalor = 2271, - partialderivative = 2287, - function = 2294, - leftarrow = 2299, - uparrow = 2300, - rightarrow = 2301, - downarrow = 2302, - blank = 2527, - soliddiamond = 2528, - checkerboard = 2529, - ht = 2530, - ff = 2531, - cr = 2532, - lf = 2533, - nl = 2536, - vt = 2537, - lowrightcorner = 2538, - uprightcorner = 2539, - upleftcorner = 2540, - lowleftcorner = 2541, - crossinglines = 2542, - horizlinescan1 = 2543, - horizlinescan3 = 2544, - horizlinescan5 = 2545, - horizlinescan7 = 2546, - horizlinescan9 = 2547, - leftt = 2548, - rightt = 2549, - bott = 2550, - topt = 2551, - vertbar = 2552, - emspace = 2721, - enspace = 2722, - em3space = 2723, - em4space = 2724, - digitspace = 2725, - punctspace = 2726, - thinspace = 2727, - hairspace = 2728, - emdash = 2729, - endash = 2730, - signifblank = 2732, - ellipsis = 2734, - doubbaselinedot = 2735, - onethird = 2736, - twothirds = 2737, - onefifth = 2738, - twofifths = 2739, - threefifths = 2740, - fourfifths = 2741, - onesixth = 2742, - fivesixths = 2743, - careof = 2744, - figdash = 2747, - leftanglebracket = 2748, - decimalpoint = 2749, - rightanglebracket = 2750, - marker = 2751, - oneeighth = 2755, - threeeighths = 2756, - fiveeighths = 2757, - seveneighths = 2758, - trademark = 2761, - signaturemark = 2762, - trademarkincircle = 2763, - leftopentriangle = 2764, - rightopentriangle = 2765, - emopencircle = 2766, - emopenrectangle = 2767, - leftsinglequotemark = 2768, - rightsinglequotemark = 2769, - leftdoublequotemark = 2770, - rightdoublequotemark = 2771, - prescription = 2772, - minutes = 2774, - seconds = 2775, - latincross = 2777, - hexagram = 2778, - filledrectbullet = 2779, - filledlefttribullet = 2780, - filledrighttribullet = 2781, - emfilledcircle = 2782, - emfilledrect = 2783, - enopencircbullet = 2784, - enopensquarebullet = 2785, - openrectbullet = 2786, - opentribulletup = 2787, - opentribulletdown = 2788, - openstar = 2789, - enfilledcircbullet = 2790, - enfilledsqbullet = 2791, - filledtribulletup = 2792, - filledtribulletdown = 2793, - leftpointer = 2794, - rightpointer = 2795, - club = 2796, - diamond = 2797, - heart = 2798, - maltesecross = 2800, - dagger = 2801, - doubledagger = 2802, - checkmark = 2803, - ballotcross = 2804, - musicalsharp = 2805, - musicalflat = 2806, - malesymbol = 2807, - femalesymbol = 2808, - telephone = 2809, - telephonerecorder = 2810, - phonographcopyright = 2811, - caret = 2812, - singlelowquotemark = 2813, - doublelowquotemark = 2814, - cursor = 2815, - leftcaret = 2979, - rightcaret = 2982, - downcaret = 2984, - upcaret = 2985, - overbar = 3008, - downtack = 3010, - upshoe = 3011, - downstile = 3012, - underbar = 3014, - jot = 3018, - quad = 3020, - uptack = 3022, - circle = 3023, - upstile = 3027, - downshoe = 3030, - rightshoe = 3032, - leftshoe = 3034, - lefttack = 3036, - righttack = 3068, - hebrew_doublelowline = 3295, - hebrew_aleph = 3296, - hebrew_bet = 3297, - hebrew_beth = 3297, - hebrew_gimel = 3298, - hebrew_gimmel = 3298, - hebrew_dalet = 3299, - hebrew_daleth = 3299, - hebrew_he = 3300, - hebrew_waw = 3301, - hebrew_zain = 3302, - hebrew_zayin = 3302, - hebrew_chet = 3303, - hebrew_het = 3303, - hebrew_tet = 3304, - hebrew_teth = 3304, - hebrew_yod = 3305, - hebrew_finalkaph = 3306, - hebrew_kaph = 3307, - hebrew_lamed = 3308, - hebrew_finalmem = 3309, - hebrew_mem = 3310, - hebrew_finalnun = 3311, - hebrew_nun = 3312, - hebrew_samech = 3313, - hebrew_samekh = 3313, - hebrew_ayin = 3314, - hebrew_finalpe = 3315, - hebrew_pe = 3316, - hebrew_finalzade = 3317, - hebrew_finalzadi = 3317, - hebrew_zade = 3318, - hebrew_zadi = 3318, - hebrew_kuf = 3319, - hebrew_qoph = 3319, - hebrew_resh = 3320, - hebrew_shin = 3321, - hebrew_taf = 3322, - hebrew_taw = 3322, - Thai_kokai = 3489, - Thai_khokhai = 3490, - Thai_khokhuat = 3491, - Thai_khokhwai = 3492, - Thai_khokhon = 3493, - Thai_khorakhang = 3494, - Thai_ngongu = 3495, - Thai_chochan = 3496, - Thai_choching = 3497, - Thai_chochang = 3498, - Thai_soso = 3499, - Thai_chochoe = 3500, - Thai_yoying = 3501, - Thai_dochada = 3502, - Thai_topatak = 3503, - Thai_thothan = 3504, - Thai_thonangmontho = 3505, - Thai_thophuthao = 3506, - Thai_nonen = 3507, - Thai_dodek = 3508, - Thai_totao = 3509, - Thai_thothung = 3510, - Thai_thothahan = 3511, - Thai_thothong = 3512, - Thai_nonu = 3513, - Thai_bobaimai = 3514, - Thai_popla = 3515, - Thai_phophung = 3516, - Thai_fofa = 3517, - Thai_phophan = 3518, - Thai_fofan = 3519, - Thai_phosamphao = 3520, - Thai_moma = 3521, - Thai_yoyak = 3522, - Thai_rorua = 3523, - Thai_ru = 3524, - Thai_loling = 3525, - Thai_lu = 3526, - Thai_wowaen = 3527, - Thai_sosala = 3528, - Thai_sorusi = 3529, - Thai_sosua = 3530, - Thai_hohip = 3531, - Thai_lochula = 3532, - Thai_oang = 3533, - Thai_honokhuk = 3534, - Thai_paiyannoi = 3535, - Thai_saraa = 3536, - Thai_maihanakat = 3537, - Thai_saraaa = 3538, - Thai_saraam = 3539, - Thai_sarai = 3540, - Thai_saraii = 3541, - Thai_saraue = 3542, - Thai_sarauee = 3543, - Thai_sarau = 3544, - Thai_sarauu = 3545, - Thai_phinthu = 3546, - Thai_maihanakat_maitho = 3550, - Thai_baht = 3551, - Thai_sarae = 3552, - Thai_saraae = 3553, - Thai_sarao = 3554, - Thai_saraaimaimuan = 3555, - Thai_saraaimaimalai = 3556, - Thai_lakkhangyao = 3557, - Thai_maiyamok = 3558, - Thai_maitaikhu = 3559, - Thai_maiek = 3560, - Thai_maitho = 3561, - Thai_maitri = 3562, - Thai_maichattawa = 3563, - Thai_thanthakhat = 3564, - Thai_nikhahit = 3565, - Thai_leksun = 3568, - Thai_leknung = 3569, - Thai_leksong = 3570, - Thai_leksam = 3571, - Thai_leksi = 3572, - Thai_lekha = 3573, - Thai_lekhok = 3574, - Thai_lekchet = 3575, - Thai_lekpaet = 3576, - Thai_lekkao = 3577, - Hangul_Kiyeog = 3745, - Hangul_SsangKiyeog = 3746, - Hangul_KiyeogSios = 3747, - Hangul_Nieun = 3748, - Hangul_NieunJieuj = 3749, - Hangul_NieunHieuh = 3750, - Hangul_Dikeud = 3751, - Hangul_SsangDikeud = 3752, - Hangul_Rieul = 3753, - Hangul_RieulKiyeog = 3754, - Hangul_RieulMieum = 3755, - Hangul_RieulPieub = 3756, - Hangul_RieulSios = 3757, - Hangul_RieulTieut = 3758, - Hangul_RieulPhieuf = 3759, - Hangul_RieulHieuh = 3760, - Hangul_Mieum = 3761, - Hangul_Pieub = 3762, - Hangul_SsangPieub = 3763, - Hangul_PieubSios = 3764, - Hangul_Sios = 3765, - Hangul_SsangSios = 3766, - Hangul_Ieung = 3767, - Hangul_Jieuj = 3768, - Hangul_SsangJieuj = 3769, - Hangul_Cieuc = 3770, - Hangul_Khieuq = 3771, - Hangul_Tieut = 3772, - Hangul_Phieuf = 3773, - Hangul_Hieuh = 3774, - Hangul_A = 3775, - Hangul_AE = 3776, - Hangul_YA = 3777, - Hangul_YAE = 3778, - Hangul_EO = 3779, - Hangul_E = 3780, - Hangul_YEO = 3781, - Hangul_YE = 3782, - Hangul_O = 3783, - Hangul_WA = 3784, - Hangul_WAE = 3785, - Hangul_OE = 3786, - Hangul_YO = 3787, - Hangul_U = 3788, - Hangul_WEO = 3789, - Hangul_WE = 3790, - Hangul_WI = 3791, - Hangul_YU = 3792, - Hangul_EU = 3793, - Hangul_YI = 3794, - Hangul_I = 3795, - Hangul_J_Kiyeog = 3796, - Hangul_J_SsangKiyeog = 3797, - Hangul_J_KiyeogSios = 3798, - Hangul_J_Nieun = 3799, - Hangul_J_NieunJieuj = 3800, - Hangul_J_NieunHieuh = 3801, - Hangul_J_Dikeud = 3802, - Hangul_J_Rieul = 3803, - Hangul_J_RieulKiyeog = 3804, - Hangul_J_RieulMieum = 3805, - Hangul_J_RieulPieub = 3806, - Hangul_J_RieulSios = 3807, - Hangul_J_RieulTieut = 3808, - Hangul_J_RieulPhieuf = 3809, - Hangul_J_RieulHieuh = 3810, - Hangul_J_Mieum = 3811, - Hangul_J_Pieub = 3812, - Hangul_J_PieubSios = 3813, - Hangul_J_Sios = 3814, - Hangul_J_SsangSios = 3815, - Hangul_J_Ieung = 3816, - Hangul_J_Jieuj = 3817, - Hangul_J_Cieuc = 3818, - Hangul_J_Khieuq = 3819, - Hangul_J_Tieut = 3820, - Hangul_J_Phieuf = 3821, - Hangul_J_Hieuh = 3822, - Hangul_RieulYeorinHieuh = 3823, - Hangul_SunkyeongeumMieum = 3824, - Hangul_SunkyeongeumPieub = 3825, - Hangul_PanSios = 3826, - Hangul_KkogjiDalrinIeung = 3827, - Hangul_SunkyeongeumPhieuf = 3828, - Hangul_YeorinHieuh = 3829, - Hangul_AraeA = 3830, - Hangul_AraeAE = 3831, - Hangul_J_PanSios = 3832, - Hangul_J_KkogjiDalrinIeung = 3833, - Hangul_J_YeorinHieuh = 3834, - Korean_Won = 3839, - OE = 5052, - oe = 5053, - Ydiaeresis = 5054, - EcuSign = 8352, - ColonSign = 8353, - CruzeiroSign = 8354, - FFrancSign = 8355, - LiraSign = 8356, - MillSign = 8357, - NairaSign = 8358, - PesetaSign = 8359, - RupeeSign = 8360, - WonSign = 8361, - NewSheqelSign = 8362, - DongSign = 8363, - EuroSign = 8364, - Key_3270_Duplicate = 64769, - Key_3270_FieldMark = 64770, - Key_3270_Right2 = 64771, - Key_3270_Left2 = 64772, - Key_3270_BackTab = 64773, - Key_3270_EraseEOF = 64774, - Key_3270_EraseInput = 64775, - Key_3270_Reset = 64776, - Key_3270_Quit = 64777, - Key_3270_PA1 = 64778, - Key_3270_PA2 = 64779, - Key_3270_PA3 = 64780, - Key_3270_Test = 64781, - Key_3270_Attn = 64782, - Key_3270_CursorBlink = 64783, - Key_3270_AltCursor = 64784, - Key_3270_KeyClick = 64785, - Key_3270_Jump = 64786, - Key_3270_Ident = 64787, - Key_3270_Rule = 64788, - Key_3270_Copy = 64789, - Key_3270_Play = 64790, - Key_3270_Setup = 64791, - Key_3270_Record = 64792, - Key_3270_ChangeScreen = 64793, - Key_3270_DeleteWord = 64794, - Key_3270_ExSelect = 64795, - Key_3270_CursorSelect = 64796, - Key_3270_PrintScreen = 64797, - Key_3270_Enter = 64798, - ISO_Lock = 65025, - ISO_Level2_Latch = 65026, - ISO_Level3_Shift = 65027, - ISO_Level3_Latch = 65028, - ISO_Level3_Lock = 65029, - ISO_Group_Latch = 65030, - ISO_Group_Lock = 65031, - ISO_Next_Group = 65032, - ISO_Next_Group_Lock = 65033, - ISO_Prev_Group = 65034, - ISO_Prev_Group_Lock = 65035, - ISO_First_Group = 65036, - ISO_First_Group_Lock = 65037, - ISO_Last_Group = 65038, - ISO_Last_Group_Lock = 65039, - ISO_Left_Tab = 65056, - ISO_Move_Line_Up = 65057, - ISO_Move_Line_Down = 65058, - ISO_Partial_Line_Up = 65059, - ISO_Partial_Line_Down = 65060, - ISO_Partial_Space_Left = 65061, - ISO_Partial_Space_Right = 65062, - ISO_Set_Margin_Left = 65063, - ISO_Set_Margin_Right = 65064, - ISO_Release_Margin_Left = 65065, - ISO_Release_Margin_Right = 65066, - ISO_Release_Both_Margins = 65067, - ISO_Fast_Cursor_Left = 65068, - ISO_Fast_Cursor_Right = 65069, - ISO_Fast_Cursor_Up = 65070, - ISO_Fast_Cursor_Down = 65071, - ISO_Continuous_Underline = 65072, - ISO_Discontinuous_Underline = 65073, - ISO_Emphasize = 65074, - ISO_Center_Object = 65075, - ISO_Enter = 65076, - dead_grave = 65104, - dead_acute = 65105, - dead_circumflex = 65106, - dead_tilde = 65107, - dead_macron = 65108, - dead_breve = 65109, - dead_abovedot = 65110, - dead_diaeresis = 65111, - dead_abovering = 65112, - dead_doubleacute = 65113, - dead_caron = 65114, - dead_cedilla = 65115, - dead_ogonek = 65116, - dead_iota = 65117, - dead_voiced_sound = 65118, - dead_semivoiced_sound = 65119, - dead_belowdot = 65120, - AccessX_Enable = 65136, - AccessX_Feedback_Enable = 65137, - RepeatKeys_Enable = 65138, - SlowKeys_Enable = 65139, - BounceKeys_Enable = 65140, - StickyKeys_Enable = 65141, - MouseKeys_Enable = 65142, - MouseKeys_Accel_Enable = 65143, - Overlay1_Enable = 65144, - Overlay2_Enable = 65145, - AudibleBell_Enable = 65146, - First_Virtual_Screen = 65232, - Prev_Virtual_Screen = 65233, - Next_Virtual_Screen = 65234, - Last_Virtual_Screen = 65236, - Terminate_Server = 65237, - Pointer_Left = 65248, - Pointer_Right = 65249, - Pointer_Up = 65250, - Pointer_Down = 65251, - Pointer_UpLeft = 65252, - Pointer_UpRight = 65253, - Pointer_DownLeft = 65254, - Pointer_DownRight = 65255, - Pointer_Button_Dflt = 65256, - Pointer_Button1 = 65257, - Pointer_Button2 = 65258, - Pointer_Button3 = 65259, - Pointer_Button4 = 65260, - Pointer_Button5 = 65261, - Pointer_DblClick_Dflt = 65262, - Pointer_DblClick1 = 65263, - Pointer_DblClick2 = 65264, - Pointer_DblClick3 = 65265, - Pointer_DblClick4 = 65266, - Pointer_DblClick5 = 65267, - Pointer_Drag_Dflt = 65268, - Pointer_Drag1 = 65269, - Pointer_Drag2 = 65270, - Pointer_Drag3 = 65271, - Pointer_Drag4 = 65272, - Pointer_EnableKeys = 65273, - Pointer_Accelerate = 65274, - Pointer_DfltBtnNext = 65275, - Pointer_DfltBtnPrev = 65276, - Pointer_Drag5 = 65277, - BackSpace = 65288, - Tab = 65289, - Linefeed = 65290, - Clear = 65291, - Return = 65293, - Pause = 65299, - Scroll_Lock = 65300, - Sys_Req = 65301, - Escape = 65307, - Multi_key = 65312, - Kanji = 65313, - Muhenkan = 65314, - Henkan = 65315, - Henkan_Mode = 65315, - Romaji = 65316, - Hiragana = 65317, - Katakana = 65318, - Hiragana_Katakana = 65319, - Zenkaku = 65320, - Hankaku = 65321, - Zenkaku_Hankaku = 65322, - Touroku = 65323, - Massyo = 65324, - Kana_Lock = 65325, - Kana_Shift = 65326, - Eisu_Shift = 65327, - Eisu_toggle = 65328, - Hangul = 65329, - Hangul_Start = 65330, - Hangul_End = 65331, - Hangul_Hanja = 65332, - Hangul_Jamo = 65333, - Hangul_Romaja = 65334, - Codeinput = 65335, - Hangul_Codeinput = 65335, - Kanji_Bangou = 65335, - Hangul_Jeonja = 65336, - Hangul_Banja = 65337, - Hangul_PreHanja = 65338, - Hangul_PostHanja = 65339, - Hangul_SingleCandidate = 65340, - SingleCandidate = 65340, - Hangul_MultipleCandidate = 65341, - MultipleCandidate = 65341, - Zen_Koho = 65341, - Hangul_PreviousCandidate = 65342, - Mae_Koho = 65342, - PreviousCandidate = 65342, - Hangul_Special = 65343, - Home = 65360, - Left = 65361, - Up = 65362, - Right = 65363, - Down = 65364, - Page_Up = 65365, - Prior = 65365, - Next = 65366, - Page_Down = 65366, - End = 65367, - Begin = 65368, - Select = 65376, - Print = 65377, - Execute = 65378, - Insert = 65379, - Undo = 65381, - Redo = 65382, - Menu = 65383, - Find = 65384, - Cancel = 65385, - Help = 65386, - Break = 65387, - Arabic_switch = 65406, - Greek_switch = 65406, - Hangul_switch = 65406, - Hebrew_switch = 65406, - ISO_Group_Shift = 65406, - Mode_switch = 65406, - kana_switch = 65406, - script_switch = 65406, - Num_Lock = 65407, - KP_Space = 65408, - KP_Tab = 65417, - KP_Enter = 65421, - KP_F1 = 65425, - KP_F2 = 65426, - KP_F3 = 65427, - KP_F4 = 65428, - KP_Home = 65429, - KP_Left = 65430, - KP_Up = 65431, - KP_Right = 65432, - KP_Down = 65433, - KP_Page_Up = 65434, - KP_Prior = 65434, - KP_Next = 65435, - KP_Page_Down = 65435, - KP_End = 65436, - KP_Begin = 65437, - KP_Insert = 65438, - KP_Delete = 65439, - KP_Multiply = 65450, - KP_Add = 65451, - KP_Separator = 65452, - KP_Subtract = 65453, - KP_Decimal = 65454, - KP_Divide = 65455, - KP_0 = 65456, - KP_1 = 65457, - KP_2 = 65458, - KP_3 = 65459, - KP_4 = 65460, - KP_5 = 65461, - KP_6 = 65462, - KP_7 = 65463, - KP_8 = 65464, - KP_9 = 65465, - KP_Equal = 65469, - F1 = 65470, - F2 = 65471, - F3 = 65472, - F4 = 65473, - F5 = 65474, - F6 = 65475, - F7 = 65476, - F8 = 65477, - F9 = 65478, - F10 = 65479, - F11 = 65480, - L1 = 65480, - F12 = 65481, - L2 = 65481, - F13 = 65482, - L3 = 65482, - F14 = 65483, - L4 = 65483, - F15 = 65484, - L5 = 65484, - F16 = 65485, - L6 = 65485, - F17 = 65486, - L7 = 65486, - F18 = 65487, - L8 = 65487, - F19 = 65488, - L9 = 65488, - F20 = 65489, - L10 = 65489, - F21 = 65490, - R1 = 65490, - F22 = 65491, - R2 = 65491, - F23 = 65492, - R3 = 65492, - F24 = 65493, - R4 = 65493, - F25 = 65494, - R5 = 65494, - F26 = 65495, - R6 = 65495, - F27 = 65496, - R7 = 65496, - F28 = 65497, - R8 = 65497, - F29 = 65498, - R9 = 65498, - F30 = 65499, - R10 = 65499, - F31 = 65500, - R11 = 65500, - F32 = 65501, - R12 = 65501, - F33 = 65502, - R13 = 65502, - F34 = 65503, - R14 = 65503, - F35 = 65504, - R15 = 65504, - Shift_L = 65505, - Shift_R = 65506, - Control_L = 65507, - Control_R = 65508, - Caps_Lock = 65509, - Shift_Lock = 65510, - Meta_L = 65511, - Meta_R = 65512, - Alt_L = 65513, - Alt_R = 65514, - Super_L = 65515, - Super_R = 65516, - Hyper_L = 65517, - Hyper_R = 65518, - Delete = 65535, - VoidSymbol = 16777215, - } -} diff --git a/src/Gtk/Avalonia.Gtk3/Gtk3ForeignX11SystemDialog.cs b/src/Gtk/Avalonia.Gtk3/Gtk3ForeignX11SystemDialog.cs deleted file mode 100644 index b80914572b..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Gtk3ForeignX11SystemDialog.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Threading; -using System.Threading.Tasks; -using Avalonia.Controls; -using Avalonia.Controls.Platform; -using Avalonia.Gtk3.Interop; -using Avalonia.Platform; -using Avalonia.Platform.Interop; - -namespace Avalonia.Gtk3 -{ - public class Gtk3ForeignX11SystemDialog : ISystemDialogImpl - { - private Task _initialized; - private SystemDialogBase _inner = new SystemDialogBase(); - - - public async Task ShowFileDialogAsync(FileDialog dialog, IWindowImpl parent) - { - await EnsureInitialized(); - var xid = parent.Handle.Handle; - return await await RunOnGtkThread( - () => _inner.ShowFileDialogAsync(dialog, GtkWindow.Null, chooser => UpdateParent(chooser, xid))); - } - - public async Task ShowFolderDialogAsync(OpenFolderDialog dialog, IWindowImpl parent) - { - await EnsureInitialized(); - var xid = parent.Handle.Handle; - return await await RunOnGtkThread( - () => _inner.ShowFolderDialogAsync(dialog, GtkWindow.Null, chooser => UpdateParent(chooser, xid))); - } - - void UpdateParent(GtkFileChooser chooser, IntPtr xid) - { - Native.GtkWidgetRealize(chooser); - var window = Native.GtkWidgetGetWindow(chooser); - var parent = Native.GdkWindowForeignNewForDisplay(GdkDisplay, xid); - if (window != IntPtr.Zero && parent != IntPtr.Zero) - Native.GdkWindowSetTransientFor(window, parent); - } - - async Task EnsureInitialized() - { - if (_initialized == null) - { - var tcs = new TaskCompletionSource(); - _initialized = tcs.Task; - new Thread(() => GtkThread(tcs)) - { - IsBackground = true - }.Start(); - } - - if (!(await _initialized)) - throw new Exception("Unable to initialize GTK on separate thread"); - - } - - Task RunOnGtkThread(Func action) - { - var tcs = new TaskCompletionSource(); - GlibTimeout.Add(0, 0, () => - { - - try - { - tcs.SetResult(action()); - } - catch (Exception e) - { - tcs.TrySetException(e); - } - - return false; - }); - return tcs.Task; - } - - - void GtkThread(TaskCompletionSource tcs) - { - try - { - X11.XInitThreads(); - }catch{} - Resolver.Resolve(); - if (Native.GdkWindowForeignNewForDisplay == null) - throw new Exception("gdk_x11_window_foreign_new_for_display is not found in your libgdk-3.so"); - using (var backends = new Utf8Buffer("x11")) - Native.GdkSetAllowedBackends?.Invoke(backends); - if (!Native.GtkInitCheck(0, IntPtr.Zero)) - { - tcs.SetResult(false); - return; - } - - using (var utf = new Utf8Buffer($"avalonia.app.a{Guid.NewGuid().ToString("N")}")) - App = Native.GtkApplicationNew(utf, 0); - if (App == IntPtr.Zero) - { - tcs.SetResult(false); - return; - } - GdkDisplay = Native.GdkGetDefaultDisplay(); - tcs.SetResult(true); - while (true) - Native.GtkMainIteration(); - } - - private IntPtr GdkDisplay { get; set; } - private IntPtr App { get; set; } - } -} diff --git a/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs b/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs deleted file mode 100644 index 965973d3cb..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs +++ /dev/null @@ -1,168 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Threading; -using Avalonia.Controls; -using Avalonia.Controls.Platform; -using Avalonia.Gtk3; -using Avalonia.Gtk3.Interop; -using Avalonia.Input; -using Avalonia.Input.Platform; -using Avalonia.OpenGL; -using Avalonia.Platform; -using Avalonia.Platform.Interop; -using Avalonia.Rendering; -using Avalonia.Threading; - -namespace Avalonia.Gtk3 -{ - public class Gtk3Platform : IWindowingPlatform, IPlatformSettings, IPlatformThreadingInterface - { - internal static readonly Gtk3Platform Instance = new Gtk3Platform(); - internal static readonly MouseDevice Mouse = new MouseDevice(); - internal static readonly KeyboardDevice Keyboard = new KeyboardDevice(); - internal static IntPtr App { get; set; } - internal static string DisplayClassName; - public static bool UseDeferredRendering = true; - private static bool s_gtkInitialized; - - static bool EnvOption(string option, bool def, bool? specified) - { - bool? Parse(string env) - { - var v = Environment.GetEnvironmentVariable("AVALONIA_GTK3_" + env); - if (v == null) - return null; - if (v.ToLowerInvariant() == "false" || v == "0") - return false; - return true; - } - - var overridden = Parse(option + "_OVERRIDE"); - if (overridden.HasValue) - return overridden.Value; - if (specified.HasValue) - return specified.Value; - var envValue = Parse(option); - return envValue ?? def; - } - - public static void Initialize(Gtk3PlatformOptions options) - { - Resolver.Custom = options.CustomResolver; - UseDeferredRendering = EnvOption("USE_DEFERRED_RENDERING", true, options.UseDeferredRendering); - var useGpu = EnvOption("USE_GPU", true, 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.a{Guid.NewGuid().ToString("N")}")) - App = Native.GtkApplicationNew(utf, 0); - //Mark current thread as UI thread - s_tlsMarker = true; - s_gtkInitialized = true; - } - AvaloniaLocator.CurrentMutable.Bind().ToConstant(Instance) - .Bind().ToSingleton() - .Bind().ToConstant(new CursorFactory()) - .Bind().ToConstant(Keyboard) - .Bind().ToConstant(Instance) - .Bind().ToConstant(Instance) - .Bind().ToSingleton() - .Bind().ToConstant(new RenderLoop()) - .Bind().ToConstant(new DefaultRenderTimer(60)) - .Bind().ToSingleton() - .Bind().ToConstant(new PlatformIconLoader()); - if (useGpu) - EglGlPlatformFeature.TryInitialize(); - } - - public IWindowImpl CreateWindow() => new WindowImpl(); - - public IEmbeddableWindowImpl CreateEmbeddableWindow() - { - throw new NotImplementedException(); - } - - public IPopupImpl CreatePopup() => new PopupImpl(); - - public Size DoubleClickSize => new Size(4, 4); - - public TimeSpan DoubleClickTime => TimeSpan.FromMilliseconds(100); //STUB - public double RenderScalingFactor { get; } = 1; - public double LayoutScalingFactor { get; } = 1; - - public void RunLoop(CancellationToken cancellationToken) - { - while (!cancellationToken.IsCancellationRequested) - Native.GtkMainIteration(); - } - - public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick) - { - var msec = interval.TotalMilliseconds; - var imsec = (uint) msec; - if (imsec == 0) - imsec = 1; - return GlibTimeout.StartTimer(GlibPriority.FromDispatcherPriority(priority), imsec, tick); - } - - private bool[] _signaled = new bool[(int) DispatcherPriority.MaxValue + 1]; - object _lock = new object(); - public void Signal(DispatcherPriority prio) - { - var idx = (int) prio; - lock(_lock) - if (!_signaled[idx]) - { - _signaled[idx] = true; - GlibTimeout.Add(GlibPriority.FromDispatcherPriority(prio), 0, () => - { - lock (_lock) - { - _signaled[idx] = false; - } - Signaled?.Invoke(prio); - return false; - }); - } - } - public event Action Signaled; - - - [ThreadStatic] - private static bool s_tlsMarker; - - public bool CurrentThreadIsLoopThread => s_tlsMarker; - } - - public class Gtk3PlatformOptions - { - public bool? UseDeferredRendering { get; set; } - public bool? UseGpuAcceleration { get; set; } - public ICustomGtk3NativeLibraryResolver CustomResolver { get; set; } - } -} - -namespace Avalonia -{ - public static class Gtk3AppBuilderExtensions - { - public static T UseGtk3(this AppBuilderBase builder, Gtk3PlatformOptions options = null) - where T : AppBuilderBase, new() - { - return builder.UseWindowingSubsystem(() => Gtk3Platform.Initialize(options ?? new Gtk3PlatformOptions()), - "GTK3"); - } - } -} diff --git a/src/Gtk/Avalonia.Gtk3/GtkScreen.cs b/src/Gtk/Avalonia.Gtk3/GtkScreen.cs deleted file mode 100644 index a2b4604130..0000000000 --- a/src/Gtk/Avalonia.Gtk3/GtkScreen.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Avalonia.Platform; - -namespace Avalonia.Gtk3 -{ - public class GtkScreen : Screen - { - private readonly int _screenId; - - public GtkScreen(PixelRect bounds, PixelRect workingArea, bool primary, int screenId) : base(bounds, workingArea, primary) - { - this._screenId = screenId; - } - - public override int GetHashCode() - { - return _screenId; - } - - public override bool Equals(object obj) - { - return (obj is GtkScreen screen) ? this._screenId == screen._screenId : base.Equals(obj); - } - } -} diff --git a/src/Gtk/Avalonia.Gtk3/IDeferredRenderOperation.cs b/src/Gtk/Avalonia.Gtk3/IDeferredRenderOperation.cs deleted file mode 100644 index e16463a2ef..0000000000 --- a/src/Gtk/Avalonia.Gtk3/IDeferredRenderOperation.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace Avalonia.Gtk3 -{ - public interface IDeferredRenderOperation : IDisposable - { - void RenderNow(IntPtr? ctx); - } -} \ No newline at end of file diff --git a/src/Gtk/Avalonia.Gtk3/ImageSurfaceFramebuffer.cs b/src/Gtk/Avalonia.Gtk3/ImageSurfaceFramebuffer.cs deleted file mode 100644 index 878689442d..0000000000 --- a/src/Gtk/Avalonia.Gtk3/ImageSurfaceFramebuffer.cs +++ /dev/null @@ -1,144 +0,0 @@ -using System; -using Avalonia.Gtk3.Interop; -using Avalonia.Platform; -using Avalonia.Threading; - - -namespace Avalonia.Gtk3 -{ - class ImageSurfaceFramebuffer : ILockedFramebuffer - { - private readonly WindowBaseImpl _impl; - private readonly GtkWidget _widget; - private ManagedCairoSurface _surface; - private int _factor; - private object _lock = new object(); - public ImageSurfaceFramebuffer(WindowBaseImpl impl, int width, int height, int factor) - { - _impl = impl; - _widget = impl.GtkWidget; - _factor = factor; - width *= _factor; - height *= _factor; - _surface = new ManagedCairoSurface(width, height); - - Size = new PixelSize(width, height); - Address = _surface.Buffer; - RowBytes = _surface.Stride; - Native.CairoSurfaceFlush(_surface.Surface); - } - - static void Draw(IntPtr context, CairoSurface surface, double factor) - { - - Native.CairoSurfaceMarkDirty(surface); - Native.CairoScale(context, 1d / factor, 1d / factor); - Native.CairoSetSourceSurface(context, surface, 0, 0); - Native.CairoPaint(context); - - } - /* - static Stopwatch St =Stopwatch.StartNew(); - private static int _frames; - private static int _fps;*/ - static void DrawToWidget(GtkWidget widget, CairoSurface surface, int width, int height, double factor) - { - if(surface == null || widget.IsClosed) - return; - var window = Native.GtkWidgetGetWindow(widget); - if(window == IntPtr.Zero) - return; - var rc = new GdkRectangle {Width = width, Height = height}; - Native.GdkWindowBeginPaintRect(window, ref rc); - var context = Native.GdkCairoCreate(window); - Draw(context, surface, factor); - /* - _frames++; - var el = St.Elapsed; - if (el.TotalSeconds > 1) - { - _fps = (int) (_frames / el.TotalSeconds); - _frames = 0; - St = Stopwatch.StartNew(); - } - - Native.CairoSetSourceRgba(context, 1, 0, 0, 1); - Native.CairoMoveTo(context, 20, 20); - Native.CairoSetFontSize(context, 30); - using (var txt = new Utf8Buffer("FPS: " + _fps)) - Native.CairoShowText(context, txt); - */ - - Native.CairoDestroy(context); - Native.GdkWindowEndPaint(window); - } - - class RenderOp : IDeferredRenderOperation - { - private readonly GtkWidget _widget; - private ManagedCairoSurface _surface; - private readonly double _factor; - private readonly int _width; - private readonly int _height; - - public RenderOp(GtkWidget widget, ManagedCairoSurface surface, double factor, int width, int height) - { - _widget = widget; - _surface = surface ?? throw new ArgumentNullException(nameof(surface)); - _factor = factor; - _width = width; - _height = height; - } - - public void Dispose() - { - _surface?.Dispose(); - _surface = null; - } - - public void RenderNow(IntPtr? ctx) - { - if(ctx.HasValue) - Draw(ctx.Value, _surface.Surface, _factor); - else - DrawToWidget(_widget, _surface.Surface, _width, _height, _factor); - } - } - - public void Dispose() - { - lock (_lock) - { - if (Dispatcher.UIThread.CheckAccess()) - { - if (_impl.CurrentCairoContext != IntPtr.Zero) - Draw(_impl.CurrentCairoContext, _surface.Surface, _factor); - else - DrawToWidget(_widget, _surface.Surface, Size.Width, Size.Height, _factor); - _surface.Dispose(); - } - else - _impl.SetNextRenderOperation(new RenderOp(_widget, _surface, _factor, Size.Width, Size.Height)); - _surface = null; - } - } - - public IntPtr Address { get; } - public PixelSize Size { get; } - public int RowBytes { get; } - - - public Vector Dpi - { - get - { - return new Vector(96, 96) * _factor; - } - } - - public PixelFormat Format => PixelFormat.Bgra8888; - } -} - - - diff --git a/src/Gtk/Avalonia.Gtk3/Interop/CairoSurface.cs b/src/Gtk/Avalonia.Gtk3/Interop/CairoSurface.cs deleted file mode 100644 index 7838be9305..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Interop/CairoSurface.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Avalonia.Gtk3.Interop -{ - class CairoSurface : SafeHandle - { - public CairoSurface() : base(IntPtr.Zero, true) - { - } - - protected override bool ReleaseHandle() - { - Native.CairoSurfaceDestroy(handle); - return true; - } - - public override bool IsInvalid => handle == IntPtr.Zero; - } -} diff --git a/src/Gtk/Avalonia.Gtk3/Interop/GException.cs b/src/Gtk/Avalonia.Gtk3/Interop/GException.cs deleted file mode 100644 index 5ff6cbe8ed..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Interop/GException.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using Avalonia.Platform.Interop; - -namespace Avalonia.Gtk3.Interop -{ - public class GException : Exception - { - [StructLayout(LayoutKind.Sequential)] - struct GError - { - UInt32 domain; - int code; - public IntPtr message; - }; - - static unsafe string GetError(IntPtr error) - { - if (error == IntPtr.Zero) - return "Unknown error"; - return Utf8Buffer.StringFromPtr(((GError*) error)->message); - } - - public GException(IntPtr error) : base(GetError(error)) - { - - } - - } -} diff --git a/src/Gtk/Avalonia.Gtk3/Interop/GObject.cs b/src/Gtk/Avalonia.Gtk3/Interop/GObject.cs deleted file mode 100644 index bb272b06d5..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Interop/GObject.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.InteropServices; - -namespace Avalonia.Gtk3.Interop -{ - class GObject : SafeHandle - { - public GObject() : base(IntPtr.Zero, true) - { - } - - public GObject(IntPtr handle, bool owned = true) : base(IntPtr.Zero, owned) - { - this.handle = handle; - } - - protected override bool ReleaseHandle() - { - if (handle != IntPtr.Zero) - { - Debug.Assert(Native.GTypeCheckInstanceIsFundamentallyA(handle, new IntPtr(Native.G_TYPE_OBJECT)), - "Handle is not a GObject"); - Native.GObjectUnref(handle); - } - - handle = IntPtr.Zero; - return true; - } - - public override bool IsInvalid => handle == IntPtr.Zero; - } - - class GInputStream : GObject - { - - } - - class GtkWidget : GObject - { - - } - - class GtkWindow : GtkWidget - { - public static GtkWindow Null { get; } = new GtkWindow(); - } - - class GtkImContext : GObject - { - } - - class GdkScreen : GObject - { - public GdkScreen() : base(IntPtr.Zero, false) - { - } - - public GdkScreen(IntPtr handle, bool owned = true) : base(handle, owned) - { - this.handle = handle; - } - } - - class UnownedGdkScreen : GdkScreen - { - public UnownedGdkScreen() : base(IntPtr.Zero, false) - { - } - - public UnownedGdkScreen(IntPtr handle, bool owned = true) : base(IntPtr.Zero, false) - { - this.handle = handle; - } - } - - class GtkDialog : GtkWindow - { - - } - - class GtkFileChooser : GtkDialog - { - - } -} - diff --git a/src/Gtk/Avalonia.Gtk3/Interop/GlibPriority.cs b/src/Gtk/Avalonia.Gtk3/Interop/GlibPriority.cs deleted file mode 100644 index 08448e30d5..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Interop/GlibPriority.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using Avalonia.Threading; - -namespace Avalonia.Gtk3.Interop -{ - static class GlibPriority - { - public static int High = -100; - public static int Default = 0; - public static int HighIdle = 100; - public static int GtkResize = HighIdle + 10; - public static int GtkPaint = HighIdle + 20; - public static int DefaultIdle = 200; - public static int Low = 300; - public static int GdkEvents = Default; - public static int GdkRedraw = HighIdle + 20; - - public static int FromDispatcherPriority(DispatcherPriority prio) - { - if (prio == DispatcherPriority.Send) - return High; - if (prio == DispatcherPriority.Normal) - return Default; - if (prio == DispatcherPriority.DataBind) - return Default + 1; - if (prio == DispatcherPriority.Layout) - return Default + 2; - if (prio == DispatcherPriority.Render) - return Default + 3; - if (prio == DispatcherPriority.Loaded) - return GtkPaint + 20; - if (prio == DispatcherPriority.Input) - return GtkPaint + 21; - if (prio == DispatcherPriority.Background) - return DefaultIdle + 1; - if (prio == DispatcherPriority.ContextIdle) - return DefaultIdle + 2; - if (prio == DispatcherPriority.ApplicationIdle) - return DefaultIdle + 3; - if (prio == DispatcherPriority.SystemIdle) - return DefaultIdle + 4; - throw new ArgumentException("Unknown priority"); - - } - } -} diff --git a/src/Gtk/Avalonia.Gtk3/Interop/GlibTimeout.cs b/src/Gtk/Avalonia.Gtk3/Interop/GlibTimeout.cs deleted file mode 100644 index 6e3840914c..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Interop/GlibTimeout.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Avalonia.Gtk3.Interop -{ - static class GlibTimeout - { - static bool Handler(IntPtr data) - { - var handle = GCHandle.FromIntPtr(data); - var cb = (Func) handle.Target; - if (!cb()) - { - handle.Free(); - return false; - } - return true; - } - - private static readonly Native.D.timeout_callback PinnedHandler; - static GlibTimeout() - { - PinnedHandler = Handler; - } - - - public static void Add(int priority, uint interval, Func callback) - { - var handle = GCHandle.Alloc(callback); - Native.GTimeoutAddFull(priority, interval, PinnedHandler, GCHandle.ToIntPtr(handle), IntPtr.Zero); - } - - class Timer : IDisposable - { - public bool Stopped; - public void Dispose() - { - - Stopped = true; - } - } - - public static IDisposable StartTimer(int priority, uint interval, Action tick) - { - var timer = new Timer (); - GlibTimeout.Add(priority, interval, - () => - { - if (timer.Stopped) - return false; - tick(); - return !timer.Stopped; - }); - - return timer; - } - } -} diff --git a/src/Gtk/Avalonia.Gtk3/Interop/ICustomGtk3NativeLibraryResolver.cs b/src/Gtk/Avalonia.Gtk3/Interop/ICustomGtk3NativeLibraryResolver.cs deleted file mode 100644 index 3b78953d1b..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Interop/ICustomGtk3NativeLibraryResolver.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Avalonia.Gtk3.Interop; - -namespace Avalonia.Gtk3 -{ - public interface ICustomGtk3NativeLibraryResolver - { - string GetName(GtkDll dll); - string BasePath { get; } - bool TrySystemFirst { get; } - string Lookup(GtkDll dll); - } -} diff --git a/src/Gtk/Avalonia.Gtk3/Interop/ManagedCairoSurface.cs b/src/Gtk/Avalonia.Gtk3/Interop/ManagedCairoSurface.cs deleted file mode 100644 index 2b0a7eae12..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Interop/ManagedCairoSurface.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using Avalonia.Platform; - -namespace Avalonia.Gtk3.Interop -{ - class ManagedCairoSurface : IDisposable - { - public IntPtr Buffer { get; private set; } - public CairoSurface Surface { get; private set; } - public int Stride { get; private set; } - private int _size; - private IRuntimePlatform _plat; - private IUnmanagedBlob _blob; - - public ManagedCairoSurface(int width, int height) - { - _plat = AvaloniaLocator.Current.GetService(); - Stride = width * 4; - _size = height * Stride; - _blob = _plat.AllocBlob(_size * 2); - Buffer = _blob.Address; - Surface = Native.CairoImageSurfaceCreateForData(Buffer, 1, width, height, Stride); - } - - public void Dispose() - { - - if (Buffer != IntPtr.Zero) - { - Surface.Dispose(); - _blob.Dispose(); - Buffer = IntPtr.Zero; - } - } - - } -} diff --git a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs b/src/Gtk/Avalonia.Gtk3/Interop/Native.cs deleted file mode 100644 index 765c19a796..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs +++ /dev/null @@ -1,790 +0,0 @@ -#pragma warning disable 649 -using System; -using System.Runtime.InteropServices; -using Avalonia.Controls; -using Avalonia.Platform.Interop; -using gdouble = System.Double; -using gint = System.Int32; -using gint16 = System.Int16; -using gint8 = System.Byte; -using guint = System.UInt32; -using guint16 = System.UInt16; -using guint32 = System.UInt32; - -namespace Avalonia.Gtk3.Interop -{ - static class Native - { - public static class D - { - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate gint16 gdk_display_get_n_screens(IntPtr display); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate UnownedGdkScreen gdk_display_get_screen(IntPtr display, gint16 num); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate UnownedGdkScreen gdk_display_get_default_screen (IntPtr display); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate gint16 gdk_screen_get_n_monitors(GdkScreen screen); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate gint16 gdk_screen_get_primary_monitor(GdkScreen screen); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate void gdk_screen_get_monitor_geometry(GdkScreen screen, gint16 num, ref GdkRectangle rect); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate void gdk_screen_get_monitor_workarea(GdkScreen screen, gint16 num, ref GdkRectangle rect); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate IntPtr gtk_application_new(Utf8Buffer appId, int flags); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_main_iteration(); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate GtkWindow gtk_window_new(GtkWindowType windowType); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate IntPtr gtk_init(int argc, IntPtr argv); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate bool gtk_init_check(int argc, IntPtr argv); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk, optional: true)] - public delegate IntPtr gdk_set_allowed_backends (Utf8Buffer backends); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_present(GtkWindow gtkWindow); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_widget_hide(GtkWidget gtkWidget); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_widget_show(GtkWidget gtkWidget); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_set_icon(GtkWindow window, Pixbuf pixbuf); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_set_modal(GtkWindow window, bool modal); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_set_transient_for(GtkWindow window, IntPtr parent); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] //No manual import - public delegate IntPtr gdk_get_native_handle(IntPtr gdkWindow); - - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate IntPtr gtk_widget_get_window(GtkWidget gtkWidget); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk, optional: true)] - public delegate uint gtk_widget_get_scale_factor(GtkWidget gtkWidget); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate IntPtr gtk_widget_get_screen(GtkWidget gtkWidget); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate IntPtr gtk_widget_set_double_buffered(GtkWidget gtkWidget, bool value); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate IntPtr gtk_widget_set_events(GtkWidget gtkWidget, uint flags); - - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate int gdk_screen_get_height(IntPtr screen); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate int gdk_screen_get_width(IntPtr screen); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate IntPtr gdk_display_get_default(); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate int gdk_window_get_origin(IntPtr gdkWindow, out int x, out int y); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate void gdk_window_resize(IntPtr gtkWindow, int width, int height); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate void gdk_window_set_override_redirect(IntPtr gdkWindow, bool value); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_widget_realize(GtkWidget gtkWidget); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_set_title(GtkWindow gtkWindow, Utf8Buffer title); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_set_resizable(GtkWindow gtkWindow, bool resizable); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_set_decorated(GtkWindow gtkWindow, bool decorated); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_set_skip_taskbar_hint(GtkWindow gtkWindow, bool setting); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate bool gtk_window_get_skip_taskbar_hint(GtkWindow gtkWindow); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_set_skip_pager_hint(GtkWindow gtkWindow, bool setting); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate bool gtk_window_get_skip_pager_hint(GtkWindow gtkWindow); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_get_size(GtkWindow gtkWindow, out int width, out int height); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_resize(GtkWindow gtkWindow, int width, int height); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_widget_set_size_request(GtkWidget widget, int width, int height); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_set_default_size(GtkWindow gtkWindow, int width, int height); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_get_position(GtkWindow gtkWindow, out int x, out int y); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_move(GtkWindow gtkWindow, int x, int y); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate GtkFileChooser gtk_file_chooser_dialog_new(Utf8Buffer title, GtkWindow parent, GtkFileChooserAction action, IntPtr ignore); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public unsafe delegate GSList* gtk_file_chooser_get_filenames(GtkFileChooser chooser); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_file_chooser_set_select_multiple(GtkFileChooser chooser, bool allow); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_file_chooser_set_filename(GtkFileChooser chooser, Utf8Buffer file); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_dialog_add_button(GtkDialog raw, Utf8Buffer button_text, GtkResponseType response_id); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate CairoSurface cairo_image_surface_create(int format, int width, int height); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate CairoSurface cairo_image_surface_create_for_data(IntPtr data, int format, int width, int height, int stride); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate IntPtr cairo_image_surface_get_data(CairoSurface surface); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate int cairo_image_surface_get_stride(CairoSurface surface); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate void cairo_surface_mark_dirty(CairoSurface surface); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate void cairo_surface_write_to_png(CairoSurface surface, Utf8Buffer path); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate void cairo_surface_flush(CairoSurface surface); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate void cairo_surface_destroy(IntPtr surface); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate void cairo_set_source_surface(IntPtr cr, CairoSurface surface, double x, double y); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate void cairo_set_source_rgba(IntPtr cr, double r, double g, double b, double a); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate void cairo_scale(IntPtr context, double sx, double sy); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate void cairo_paint(IntPtr context); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate void cairo_show_text(IntPtr context, Utf8Buffer text); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate void cairo_set_font_size(IntPtr context, double size); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate void cairo_select_font_face(IntPtr context, Utf8Buffer face, int slant, int weight); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate void cairo_move_to(IntPtr context, double x, double y); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)] - public delegate void cairo_destroy(IntPtr context); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_widget_queue_draw_area(GtkWidget widget, int x, int y, int width, int height); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate uint gtk_widget_add_tick_callback(GtkWidget widget, TickCallback callback, IntPtr userData, IntPtr destroy); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate uint gtk_widget_remove_tick_callback(GtkWidget widget, uint id); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate GtkImContext gtk_im_multicontext_new(); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate IntPtr gtk_im_context_set_client_window(GtkImContext context, IntPtr window); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate bool gtk_im_context_filter_keypress(GtkImContext context, IntPtr ev); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_widget_activate(GtkWidget widget); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate IntPtr gdk_screen_get_root_window(IntPtr screen); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate IntPtr gdk_cursor_new(GdkCursorType type); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate IntPtr gdk_window_get_pointer(IntPtr raw, out int x, out int y, out int mask); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate GdkWindowState gdk_window_get_state(IntPtr window); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_iconify(GtkWindow window); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_deiconify(GtkWindow window); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_maximize(GtkWindow window); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_unmaximize(GtkWindow window); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_close(GtkWindow window); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_set_keep_above(GtkWindow gtkWindow, bool setting); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_window_set_geometry_hints(GtkWindow window, IntPtr geometry_widget, ref GdkGeometry geometry, GdkWindowHints geom_mask); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate void gdk_window_invalidate_rect(IntPtr window, ref GdkRectangle rect, bool invalidate_children); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate void gdk_window_begin_move_drag(IntPtr window, gint button, gint root_x, gint root_y, guint32 timestamp); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate void gdk_window_begin_resize_drag(IntPtr window, WindowEdge edge, gint button, gint root_x, gint root_y, guint32 timestamp); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate void gdk_window_process_updates(IntPtr window, bool updateChildren); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate void gdk_window_begin_paint_rect(IntPtr window, ref GdkRectangle rect); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate void gdk_window_end_paint(IntPtr window); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk, optional: true)] - public delegate IntPtr gdk_x11_window_foreign_new_for_display(IntPtr display, IntPtr xid); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate void gdk_window_set_transient_for(IntPtr window, IntPtr parent); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate void gdk_event_request_motions(IntPtr ev); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate IntPtr gtk_clipboard_get_for_display(IntPtr display, IntPtr atom); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_clipboard_request_text(IntPtr clipboard, GtkClipboardTextReceivedFunc callback, IntPtr user_data); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_clipboard_set_text(IntPtr clipboard, Utf8Buffer text, int len); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate void gtk_clipboard_clear(IntPtr clipboard); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.GdkPixBuf)] - public delegate IntPtr gdk_pixbuf_new_from_file(Utf8Buffer filename, out IntPtr error); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate IntPtr gtk_icon_theme_get_default(); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] - public delegate IntPtr gtk_icon_theme_load_icon(IntPtr icon_theme, Utf8Buffer icon_name, gint size, int flags,out IntPtr error); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate IntPtr gdk_cursor_new_from_pixbuf(IntPtr disp, IntPtr pixbuf, int x, int y); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate IntPtr gdk_window_set_cursor(IntPtr window, IntPtr cursor); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.GdkPixBuf)] - public delegate IntPtr gdk_pixbuf_new_from_stream(GInputStream stream, IntPtr cancel, out IntPtr error); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.GdkPixBuf)] - public delegate bool gdk_pixbuf_save_to_bufferv(Pixbuf pixbuf, out IntPtr buffer, out IntPtr buffer_size, - Utf8Buffer type, IntPtr option_keys, IntPtr option_values, out IntPtr error); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] - public delegate IntPtr gdk_cairo_create(IntPtr window); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)] - public delegate void g_object_unref(IntPtr instance); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)] - public delegate void g_object_ref(GObject instance); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)] - public delegate IntPtr g_type_name(IntPtr instance); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)] - public delegate ulong g_signal_connect_object(GObject instance, Utf8Buffer signal, IntPtr handler, IntPtr userData, int flags); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)] - public delegate ulong g_signal_handler_disconnect(GObject instance, ulong connectionId); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Glib)] - public delegate ulong g_timeout_add(uint interval, timeout_callback callback, IntPtr data); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Glib)] - public delegate ulong g_timeout_add_full(int prio, uint interval, timeout_callback callback, IntPtr data, IntPtr destroy); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Glib)] - public delegate ulong g_free(IntPtr data); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)] - public delegate bool g_type_check_instance_is_fundamentally_a(IntPtr instance, IntPtr type); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Glib)] - public unsafe delegate void g_slist_free(GSList* data); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gio)] - public delegate GInputStream g_memory_input_stream_new_from_data(IntPtr ptr, IntPtr len, IntPtr destroyCallback); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate bool signal_widget_draw(IntPtr gtkWidget, IntPtr cairoContext, IntPtr userData); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate bool signal_generic(IntPtr gtkWidget, IntPtr userData); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate bool signal_dialog_response(IntPtr gtkWidget, GtkResponseType response, IntPtr userData); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate bool signal_onevent(IntPtr gtkWidget, IntPtr ev, IntPtr userData); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void monitors_changed(IntPtr screen, IntPtr userData); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate bool signal_commit(IntPtr gtkWidget, IntPtr utf8string, IntPtr userData); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate bool timeout_callback(IntPtr data); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void GtkClipboardTextReceivedFunc(IntPtr clipboard, IntPtr utf8string, IntPtr userdata); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate bool TickCallback(IntPtr widget, IntPtr clock, IntPtr userdata); - - - } - - public static D.gdk_display_get_n_screens GdkDisplayGetNScreens; - public static D.gdk_display_get_screen GdkDisplayGetScreen; - public static D.gdk_display_get_default_screen GdkDisplayGetDefaultScreen; - public static D.gdk_screen_get_n_monitors GdkScreenGetNMonitors; - public static D.gdk_screen_get_primary_monitor GdkScreenGetPrimaryMonitor; - public static D.gdk_screen_get_monitor_geometry GdkScreenGetMonitorGeometry; - public static D.gdk_screen_get_monitor_workarea GdkScreenGetMonitorWorkarea; - public static D.gtk_window_set_decorated GtkWindowSetDecorated; - public static D.gtk_window_set_resizable GtkWindowSetResizable; - public static D.gtk_window_set_skip_taskbar_hint GtkWindowSetSkipTaskbarHint; - public static D.gtk_window_get_skip_taskbar_hint GtkWindowGetSkipTaskbarHint; - public static D.gtk_window_set_skip_pager_hint GtkWindowSetSkipPagerHint; - public static D.gtk_window_get_skip_pager_hint GtkWindowGetSkipPagerHint; - public static D.gtk_window_set_title GtkWindowSetTitle; - public static D.gtk_application_new GtkApplicationNew; - public static D.gtk_main_iteration GtkMainIteration; - public static D.gtk_window_new GtkWindowNew; - public static D.gtk_window_set_icon GtkWindowSetIcon; - public static D.gtk_window_set_modal GtkWindowSetModal; - public static D.gtk_window_set_transient_for GtkWindowSetTransientFor; - public static D.gdk_set_allowed_backends GdkSetAllowedBackends; - public static D.gtk_init GtkInit; - public static D.gtk_init_check GtkInitCheck; - public static D.gtk_window_present GtkWindowPresent; - public static D.gtk_widget_hide GtkWidgetHide; - public static D.gtk_widget_show GtkWidgetShow; - public static D.gdk_get_native_handle GetNativeGdkWindowHandle; - public static D.gtk_widget_get_window GtkWidgetGetWindow; - public static D.gtk_widget_get_scale_factor GtkWidgetGetScaleFactor; - public static D.gtk_widget_get_screen GtkWidgetGetScreen; - public static D.gtk_widget_realize GtkWidgetRealize; - public static D.gtk_window_get_size GtkWindowGetSize; - public static D.gtk_window_resize GtkWindowResize; - public static D.gdk_window_resize GdkWindowResize; - public static D.gdk_window_set_override_redirect GdkWindowSetOverrideRedirect; - public static D.gtk_widget_set_size_request GtkWindowSetSizeRequest; - public static D.gtk_window_set_default_size GtkWindowSetDefaultSize; - public static D.gtk_window_set_geometry_hints GtkWindowSetGeometryHints; - public static D.gtk_window_get_position GtkWindowGetPosition; - public static D.gtk_window_move GtkWindowMove; - public static D.gtk_file_chooser_dialog_new GtkFileChooserDialogNew; - public static D.gtk_file_chooser_set_select_multiple GtkFileChooserSetSelectMultiple; - public static D.gtk_file_chooser_set_filename GtkFileChooserSetFilename; - public static D.gtk_file_chooser_get_filenames GtkFileChooserGetFilenames; - public static D.gtk_dialog_add_button GtkDialogAddButton; - public static D.g_object_unref GObjectUnref; - public static D.g_object_ref GObjectRef; - public static D.g_type_name GTypeName; - public static D.g_signal_connect_object GSignalConnectObject; - public static D.g_signal_handler_disconnect GSignalHandlerDisconnect; - public static D.g_timeout_add GTimeoutAdd; - public static D.g_timeout_add_full GTimeoutAddFull; - public static D.g_free GFree; - public static D.g_type_check_instance_is_fundamentally_a GTypeCheckInstanceIsFundamentallyA; - public static D.g_slist_free GSlistFree; - public static D.g_memory_input_stream_new_from_data GMemoryInputStreamNewFromData; - public static D.gtk_widget_set_double_buffered GtkWidgetSetDoubleBuffered; - public static D.gtk_widget_set_events GtkWidgetSetEvents; - public static D.gdk_window_invalidate_rect GdkWindowInvalidateRect; - public static D.gtk_widget_queue_draw_area GtkWidgetQueueDrawArea; - public static D.gtk_widget_add_tick_callback GtkWidgetAddTickCallback; - public static D.gtk_widget_remove_tick_callback GtkWidgetRemoveTickCallback; - public static D.gtk_widget_activate GtkWidgetActivate; - public static D.gtk_clipboard_get_for_display GtkClipboardGetForDisplay; - public static D.gtk_clipboard_request_text GtkClipboardRequestText; - public static D.gtk_clipboard_set_text GtkClipboardSetText; - public static D.gtk_clipboard_clear GtkClipboardRequestClear; - - public static D.gtk_im_multicontext_new GtkImMulticontextNew; - public static D.gtk_im_context_filter_keypress GtkImContextFilterKeypress; - public static D.gtk_im_context_set_client_window GtkImContextSetClientWindow; - - public static D.gdk_screen_get_height GdkScreenGetHeight; - public static D.gdk_display_get_default GdkGetDefaultDisplay; - public static D.gdk_screen_get_width GdkScreenGetWidth; - public static D.gdk_screen_get_root_window GdkScreenGetRootWindow; - public static D.gdk_cursor_new GdkCursorNew; - public static D.gdk_window_get_origin GdkWindowGetOrigin; - public static D.gdk_window_get_pointer GdkWindowGetPointer; - public static D.gdk_window_get_state GdkWindowGetState; - public static D.gtk_window_iconify GtkWindowIconify; - public static D.gtk_window_deiconify GtkWindowDeiconify; - public static D.gtk_window_maximize GtkWindowMaximize; - public static D.gtk_window_unmaximize GtkWindowUnmaximize; - public static D.gtk_window_close GtkWindowClose; - public static D.gtk_window_set_keep_above GtkWindowSetKeepAbove; - public static D.gdk_window_begin_move_drag GdkWindowBeginMoveDrag; - public static D.gdk_window_begin_resize_drag GdkWindowBeginResizeDrag; - public static D.gdk_event_request_motions GdkEventRequestMotions; - public static D.gdk_window_process_updates GdkWindowProcessUpdates; - public static D.gdk_window_begin_paint_rect GdkWindowBeginPaintRect; - public static D.gdk_window_end_paint GdkWindowEndPaint; - public static D.gdk_x11_window_foreign_new_for_display GdkWindowForeignNewForDisplay; - public static D.gdk_window_set_transient_for GdkWindowSetTransientFor; - - public static D.gdk_pixbuf_new_from_file GdkPixbufNewFromFile; - public static D.gtk_icon_theme_get_default GtkIconThemeGetDefault; - public static D.gtk_icon_theme_load_icon GtkIconThemeLoadIcon; - public static D.gdk_cursor_new_from_pixbuf GdkCursorNewFromPixbuf; - public static D.gdk_window_set_cursor GdkWindowSetCursor; - public static D.gdk_pixbuf_new_from_stream GdkPixbufNewFromStream; - public static D.gdk_pixbuf_save_to_bufferv GdkPixbufSaveToBufferv; - public static D.gdk_cairo_create GdkCairoCreate; - - public static D.cairo_image_surface_create CairoImageSurfaceCreate; - public static D.cairo_image_surface_create_for_data CairoImageSurfaceCreateForData; - public static D.cairo_image_surface_get_data CairoImageSurfaceGetData; - public static D.cairo_image_surface_get_stride CairoImageSurfaceGetStride; - public static D.cairo_surface_mark_dirty CairoSurfaceMarkDirty; - public static D.cairo_surface_write_to_png CairoSurfaceWriteToPng; - public static D.cairo_surface_flush CairoSurfaceFlush; - public static D.cairo_surface_destroy CairoSurfaceDestroy; - public static D.cairo_set_source_surface CairoSetSourceSurface; - public static D.cairo_set_source_rgba CairoSetSourceRgba; - public static D.cairo_scale CairoScale; - public static D.cairo_paint CairoPaint; - public static D.cairo_show_text CairoShowText; - public static D.cairo_select_font_face CairoSelectFontFace; - public static D.cairo_set_font_size CairoSetFontSize; - public static D.cairo_move_to CairoMoveTo; - public static D.cairo_destroy CairoDestroy; - - public const int G_TYPE_OBJECT = 80; - } - - public enum GtkWindowType - { - TopLevel, - Popup - } - - [StructLayout(LayoutKind.Sequential)] - public struct GdkRectangle - { - public int X, Y, Width, Height; - - public static GdkRectangle FromRect(Rect rect) - { - return new GdkRectangle - { - X = (int) rect.X, - Y = (int) rect.Y, - Width = (int) rect.Width, - Height = (int) rect.Height - }; - } - } - - enum GdkEventType - { - Nothing = -1, - Delete = 0, - Destroy = 1, - Expose = 2, - MotionNotify = 3, - ButtonPress = 4, - TwoButtonPress = 5, - ThreeButtonPress = 6, - ButtonRelease = 7, - KeyPress = 8, - KeyRelease = 9, - EnterNotify = 10, - LeaveNotify = 11, - FocusChange = 12, - Configure = 13, - Map = 14, - Unmap = 15, - PropertyNotify = 16, - SelectionClear = 17, - SelectionRequest = 18, - SelectionNotify = 19, - ProximityIn = 20, - ProximityOut = 21, - DragEnter = 22, - DragLeave = 23, - DragMotion = 24, - DragStatus = 25, - DropStart = 26, - DropFinished = 27, - ClientEvent = 28, - VisibilityNotify = 29, - NoExpose = 30, - Scroll = 31, - WindowState = 32, - Setting = 33, - OwnerChange = 34, - GrabBroken = 35, - } - - enum GdkModifierType - { - ShiftMask = 1, - LockMask = 2, - ControlMask = 4, - Mod1Mask = 8, - Mod2Mask = 16, - Mod3Mask = 32, - Mod4Mask = 64, - Mod5Mask = 128, - Button1Mask = 256, - Button2Mask = 512, - Button3Mask = 1024, - Button4Mask = 2048, - Button5Mask = 4096, - SuperMask = 67108864, - HyperMask = 134217728, - MetaMask = 268435456, - ReleaseMask = 1073741824, - ModifierMask = ReleaseMask | Button5Mask | Button4Mask | Button3Mask | Button2Mask | Button1Mask | Mod5Mask | Mod4Mask | Mod3Mask | Mod2Mask | Mod1Mask | ControlMask | LockMask | ShiftMask, - None = 0, - } - - enum GdkScrollDirection - { - Up, - Down, - Left, - Right, - Smooth - } - - [StructLayout(LayoutKind.Sequential)] - unsafe struct GdkEventButton - { - public GdkEventType type; - public IntPtr window; - public gint8 send_event; - public guint32 time; - public gdouble x; - public gdouble y; - public gdouble* axes; - public GdkModifierType state; - public guint button; - public IntPtr device; - public gdouble x_root, y_root; - } - - [StructLayout(LayoutKind.Sequential)] - unsafe struct GdkEventMotion - { - public GdkEventType type; - public IntPtr window; - public gint8 send_event; - public guint32 time; - public gdouble x; - public gdouble y; - public gdouble* axes; - public GdkModifierType state; - public gint16 is_hint; - public IntPtr device; - public gdouble x_root, y_root; - } - - [StructLayout(LayoutKind.Sequential)] - unsafe struct GdkEventScroll - { - public GdkEventType type; - public IntPtr window; - public gint8 send_event; - public guint32 time; - public gdouble x; - public gdouble y; - public GdkModifierType state; - public GdkScrollDirection direction; - public IntPtr device; - public gdouble x_root, y_root; - public gdouble delta_x; - public gdouble delta_y; - } - - [StructLayout(LayoutKind.Sequential)] - unsafe struct GdkEventCrossing - { - public GdkEventType type; - public IntPtr window; - public gint8 send_event; - public IntPtr subwindow; - public guint32 time; - public gdouble x; - public gdouble y; - public gdouble x_root; - public gdouble y_root; - public int mode; - public int detail; - public bool focus; - public GdkModifierType state; - }; - - [StructLayout(LayoutKind.Sequential)] - unsafe struct GdkEventWindowState - { - public GdkEventType type; - public IntPtr window; - gint8 send_event; - public GdkWindowState changed_mask; - public GdkWindowState new_window_state; - } - - [StructLayout(LayoutKind.Sequential)] - unsafe struct GdkEventKey - { - public GdkEventType type; - public IntPtr window; - public gint8 send_event; - public guint32 time; - public guint state; - public guint keyval; - public gint length; - public IntPtr pstring; - public guint16 hardware_keycode; - public byte group; - public guint is_modifier; - } - - [StructLayout(LayoutKind.Sequential)] - unsafe struct GSList - { - public IntPtr Data; - public GSList* Next; - } - - [Flags] - public enum GdkWindowState - { - Withdrawn = 1, - Iconified = 2, - Maximized = 4, - Sticky = 8, - Fullscreen = 16, - Above = 32, - Below = 64, - Focused = 128, - Ttiled = 256 - } - - public enum GtkResponseType - { - Help = -11, - Apply = -10, - No = -9, - Yes = -8, - Close = -7, - Cancel = -6, - Ok = -5, - DeleteEvent = -4, - Accept = -3, - Reject = -2, - None = -1, - } - - public enum GtkFileChooserAction - { - Open, - Save, - SelectFolder, - CreateFolder, - } - - [StructLayout(LayoutKind.Sequential)] - public struct GdkGeometry - { - public gint min_width; - public gint min_height; - public gint max_width; - public gint max_height; - public gint base_width; - public gint base_height; - public gint width_inc; - public gint height_inc; - public gdouble min_aspect; - public gdouble max_aspect; - public gint win_gravity; - } - - enum GdkWindowHints - { - GDK_HINT_POS = 1 << 0, - GDK_HINT_MIN_SIZE = 1 << 1, - GDK_HINT_MAX_SIZE = 1 << 2, - GDK_HINT_BASE_SIZE = 1 << 3, - GDK_HINT_ASPECT = 1 << 4, - GDK_HINT_RESIZE_INC = 1 << 5, - GDK_HINT_WIN_GRAVITY = 1 << 6, - GDK_HINT_USER_POS = 1 << 7, - GDK_HINT_USER_SIZE = 1 << 8 - } -} diff --git a/src/Gtk/Avalonia.Gtk3/Interop/NativeException.cs b/src/Gtk/Avalonia.Gtk3/Interop/NativeException.cs deleted file mode 100644 index 64cbccbd26..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Interop/NativeException.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; - -namespace Avalonia.Gtk3.Interop -{ - public class NativeException : Exception - { - public NativeException() - { - } - - public NativeException(string message) : base(message) - { - } - - public NativeException(string message, Exception inner) : base(message, inner) - { - } - - } -} diff --git a/src/Gtk/Avalonia.Gtk3/Interop/Pixbuf.cs b/src/Gtk/Avalonia.Gtk3/Interop/Pixbuf.cs deleted file mode 100644 index 322b9bdfae..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Interop/Pixbuf.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using System.IO; -using System.Runtime.InteropServices; -using Avalonia.Platform; -using Avalonia.Platform.Interop; - -namespace Avalonia.Gtk3.Interop -{ - internal class Pixbuf : GObject, IWindowIconImpl - { - Pixbuf(IntPtr handle) : base(handle) - { - - } - - public static Pixbuf NewFromFile(string filename) - { - using (var ub = new Utf8Buffer(filename)) - { - IntPtr err; - var rv = Native.GdkPixbufNewFromFile(ub, out err); - if(rv != IntPtr.Zero) - return new Pixbuf(rv); - throw new GException(err); - } - } - - public static unsafe Pixbuf NewFromBytes(byte[] data) - { - fixed (void* bytes = data) - { - using (var stream = Native.GMemoryInputStreamNewFromData(new IntPtr(bytes), new IntPtr(data.Length), IntPtr.Zero)) - { - IntPtr err; - var rv = Native.GdkPixbufNewFromStream(stream, IntPtr.Zero, out err); - if (rv != IntPtr.Zero) - return new Pixbuf(rv); - throw new GException(err); - } - } - } - - public static Pixbuf NewFromStream(Stream s) - { - if (s is MemoryStream) - return NewFromBytes(((MemoryStream) s).ToArray()); - var ms = new MemoryStream(); - s.CopyTo(ms); - return NewFromBytes(ms.ToArray()); - } - - public void Save(Stream outputStream) - { - IntPtr buffer, bufferLen, error; - using (var png = new Utf8Buffer("png")) - if (!Native.GdkPixbufSaveToBufferv(this, out buffer, out bufferLen, png, - IntPtr.Zero, IntPtr.Zero, out error)) - throw new GException(error); - var data = new byte[bufferLen.ToInt32()]; - Marshal.Copy(buffer, data, 0, bufferLen.ToInt32()); - Native.GFree(buffer); - outputStream.Write(data, 0, data.Length); - } - } -} diff --git a/src/Gtk/Avalonia.Gtk3/Interop/Resolver.cs b/src/Gtk/Avalonia.Gtk3/Interop/Resolver.cs deleted file mode 100644 index c39cb9e394..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Interop/Resolver.cs +++ /dev/null @@ -1,156 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using Avalonia.Platform; -using Avalonia.Platform.Interop; - -namespace Avalonia.Gtk3.Interop -{ - internal class GtkImportAttribute : Attribute - { - public GtkDll Dll { get; set; } - public string Name { get; set; } - public bool Optional { get; set; } - - public GtkImportAttribute(GtkDll dll, string name = null, bool optional = false) - { - Dll = dll; - Name = name; - Optional = optional; - } - } - - public enum GtkDll - { - Gdk, - Gtk, - Glib, - Gio, - Gobject, - Cairo, - GdkPixBuf - } - - static class Resolver - { - private static Lazy Platform = - new Lazy( - () => AvaloniaLocator.Current.GetService().GetRuntimeInfo().OperatingSystem); - - public static ICustomGtk3NativeLibraryResolver Custom { get; set; } - - - static string FormatName(string name, int version = 0) - { - if (Platform.Value == OperatingSystemType.WinNT) - return "lib" + name + "-" + version + ".dll"; - if (Platform.Value == OperatingSystemType.Linux) - return "lib" + name + ".so" + "." + version; - if (Platform.Value == OperatingSystemType.OSX) - return "lib" + name + "." + version + ".dylib"; - throw new Exception("Unknown platform, use custom name resolver"); - } - - - - static string GetDllName(GtkDll dll) - { - var name = Custom?.GetName(dll); - if (name != null) - return name; - - switch (dll) - { - case GtkDll.Cairo: - return FormatName("cairo", 2); - case GtkDll.Gdk: - return FormatName("gdk-3"); - case GtkDll.Glib: - return FormatName("glib-2.0"); - case GtkDll.Gio: - return FormatName("gio-2.0"); - case GtkDll.Gtk: - return FormatName("gtk-3"); - case GtkDll.Gobject: - return FormatName("gobject-2.0"); - case GtkDll.GdkPixBuf: - return FormatName("gdk_pixbuf-2.0"); - default: - throw new ArgumentException("Unknown lib: " + dll); - } - } - - static IntPtr LoadDll(IDynamicLibraryLoader loader, GtkDll dll) - { - - var exceptions = new List(); - - var name = GetDllName(dll); - if (Custom?.TrySystemFirst != false) - { - try - { - return loader.LoadLibrary(name); - } - catch (Exception e) - { - exceptions.Add(e); - } - } - var path = Custom?.Lookup(dll); - if (path == null && Custom?.BasePath != null) - path = Path.Combine(Custom.BasePath, name); - if (path != null) - { - try - { - return loader.LoadLibrary(path); - } - catch (Exception e) - { - exceptions.Add(e); - } - } - throw new AggregateException("Unable to load " + dll, exceptions); - } - - public static void Resolve(string basePath = null) - { - var loader = AvaloniaLocator.Current.GetService(); - - var dlls = Enum.GetValues(typeof(GtkDll)).Cast().ToDictionary(x => x, x => LoadDll(loader, x)); - - foreach (var fieldInfo in typeof(Native).GetTypeInfo().DeclaredFields) - { - var import = fieldInfo.FieldType.GetTypeInfo().GetCustomAttributes(typeof(GtkImportAttribute), true).Cast().FirstOrDefault(); - if(import == null) - continue; - IntPtr lib = dlls[import.Dll]; - - var funcPtr = loader.GetProcAddress(lib, import.Name ?? fieldInfo.FieldType.Name, import.Optional); - - if (funcPtr != IntPtr.Zero) - fieldInfo.SetValue(null, Marshal.GetDelegateForFunctionPointer(funcPtr, fieldInfo.FieldType)); - } - - var nativeHandleNames = new[] { "gdk_win32_window_get_handle", "gdk_x11_window_get_xid", "gdk_quartz_window_get_nswindow" }; - foreach (var name in nativeHandleNames) - { - var ptr = loader.GetProcAddress(dlls[GtkDll.Gdk], name, true); - if (ptr == IntPtr.Zero) - continue; - Native.GetNativeGdkWindowHandle = (Native.D.gdk_get_native_handle) Marshal - .GetDelegateForFunctionPointer(ptr, typeof(Native.D.gdk_get_native_handle)); - } - if (Native.GetNativeGdkWindowHandle == null) - throw new Exception($"Unable to locate any of [{string.Join(", ", nativeHandleNames)}] in libgdk"); - - } - - - } -} - diff --git a/src/Gtk/Avalonia.Gtk3/Interop/Signal.cs b/src/Gtk/Avalonia.Gtk3/Interop/Signal.cs deleted file mode 100644 index 8eaca93152..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Interop/Signal.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using Avalonia.Platform.Interop; - -namespace Avalonia.Gtk3.Interop -{ - class Signal - { - class ConnectedSignal : IDisposable - { - private readonly GObject _instance; - private GCHandle _handle; - private readonly ulong _id; - - public ConnectedSignal(GObject instance, GCHandle handle, ulong id) - { - _instance = instance; - Native.GObjectRef(instance); - _handle = handle; - _id = id; - } - - public void Dispose() - { - if (_handle.IsAllocated) - { - Native.GObjectUnref(_instance.DangerousGetHandle()); - Native.GSignalHandlerDisconnect(_instance, _id); - _handle.Free(); - } - } - } - - public static IDisposable Connect(GObject obj, string name, T handler) - { - var handle = GCHandle.Alloc(handler); - var ptr = Marshal.GetFunctionPointerForDelegate((Delegate)(object)handler); - using (var utf = new Utf8Buffer(name)) - { - var id = Native.GSignalConnectObject(obj, utf, ptr, IntPtr.Zero, 0); - if (id == 0) - throw new ArgumentException("Unable to connect to signal " + name); - return new ConnectedSignal(obj, handle, id); - } - } - } -} diff --git a/src/Gtk/Avalonia.Gtk3/KeyTransform.cs b/src/Gtk/Avalonia.Gtk3/KeyTransform.cs deleted file mode 100644 index 4299e07094..0000000000 --- a/src/Gtk/Avalonia.Gtk3/KeyTransform.cs +++ /dev/null @@ -1,230 +0,0 @@ -using System.Collections.Generic; -using Avalonia.Gtk3; -using Avalonia.Input; - -namespace Avalonia.Gtk.Common -{ - static class KeyTransform - { - private static readonly Dictionary KeyDic = new Dictionary - { - { GdkKey.Cancel, Key.Cancel }, - { GdkKey.BackSpace, Key.Back }, - { GdkKey.Tab, Key.Tab }, - { GdkKey.Linefeed, Key.LineFeed }, - { GdkKey.Clear, Key.Clear }, - { GdkKey.Return, Key.Return }, - { GdkKey.KP_Enter, Key.Return }, - { GdkKey.Pause, Key.Pause }, - { GdkKey.Caps_Lock, Key.CapsLock }, - //{ GdkKey.?, Key.HangulMode } - //{ GdkKey.?, Key.JunjaMode } - //{ GdkKey.?, Key.FinalMode } - //{ GdkKey.?, Key.KanjiMode } - { GdkKey.Escape, Key.Escape }, - //{ GdkKey.?, Key.ImeConvert } - //{ GdkKey.?, Key.ImeNonConvert } - //{ GdkKey.?, Key.ImeAccept } - //{ GdkKey.?, Key.ImeModeChange } - { GdkKey.space, Key.Space }, - { GdkKey.Prior, Key.Prior }, - { GdkKey.KP_Prior, Key.Prior }, - { GdkKey.Page_Down, Key.PageDown }, - { GdkKey.KP_Page_Down, Key.PageDown }, - { GdkKey.End, Key.End }, - { GdkKey.KP_End, Key.End }, - { GdkKey.Home, Key.Home }, - { GdkKey.KP_Home, Key.Home }, - { GdkKey.Left, Key.Left }, - { GdkKey.KP_Left, Key.Left }, - { GdkKey.Up, Key.Up }, - { GdkKey.KP_Up, Key.Up }, - { GdkKey.Right, Key.Right }, - { GdkKey.KP_Right, Key.Right }, - { GdkKey.Down, Key.Down }, - { GdkKey.KP_Down, Key.Down }, - { GdkKey.Select, Key.Select }, - { GdkKey.Print, Key.Print }, - { GdkKey.Execute, Key.Execute }, - //{ GdkKey.?, Key.Snapshot } - { GdkKey.Insert, Key.Insert }, - { GdkKey.KP_Insert, Key.Insert }, - { GdkKey.Delete, Key.Delete }, - { GdkKey.KP_Delete, Key.Delete }, - { GdkKey.Help, Key.Help }, - { GdkKey.Key_0, Key.D0 }, - { GdkKey.Key_1, Key.D1 }, - { GdkKey.Key_2, Key.D2 }, - { GdkKey.Key_3, Key.D3 }, - { GdkKey.Key_4, Key.D4 }, - { GdkKey.Key_5, Key.D5 }, - { GdkKey.Key_6, Key.D6 }, - { GdkKey.Key_7, Key.D7 }, - { GdkKey.Key_8, Key.D8 }, - { GdkKey.Key_9, Key.D9 }, - { GdkKey.A, Key.A }, - { GdkKey.B, Key.B }, - { GdkKey.C, Key.C }, - { GdkKey.D, Key.D }, - { GdkKey.E, Key.E }, - { GdkKey.F, Key.F }, - { GdkKey.G, Key.G }, - { GdkKey.H, Key.H }, - { GdkKey.I, Key.I }, - { GdkKey.J, Key.J }, - { GdkKey.K, Key.K }, - { GdkKey.L, Key.L }, - { GdkKey.M, Key.M }, - { GdkKey.N, Key.N }, - { GdkKey.O, Key.O }, - { GdkKey.P, Key.P }, - { GdkKey.Q, Key.Q }, - { GdkKey.R, Key.R }, - { GdkKey.S, Key.S }, - { GdkKey.T, Key.T }, - { GdkKey.U, Key.U }, - { GdkKey.V, Key.V }, - { GdkKey.W, Key.W }, - { GdkKey.X, Key.X }, - { GdkKey.Y, Key.Y }, - { GdkKey.Z, Key.Z }, - { GdkKey.a, Key.A }, - { GdkKey.b, Key.B }, - { GdkKey.c, Key.C }, - { GdkKey.d, Key.D }, - { GdkKey.e, Key.E }, - { GdkKey.f, Key.F }, - { GdkKey.g, Key.G }, - { GdkKey.h, Key.H }, - { GdkKey.i, Key.I }, - { GdkKey.j, Key.J }, - { GdkKey.k, Key.K }, - { GdkKey.l, Key.L }, - { GdkKey.m, Key.M }, - { GdkKey.n, Key.N }, - { GdkKey.o, Key.O }, - { GdkKey.p, Key.P }, - { GdkKey.q, Key.Q }, - { GdkKey.r, Key.R }, - { GdkKey.s, Key.S }, - { GdkKey.t, Key.T }, - { GdkKey.u, Key.U }, - { GdkKey.v, Key.V }, - { GdkKey.w, Key.W }, - { GdkKey.x, Key.X }, - { GdkKey.y, Key.Y }, - { GdkKey.z, Key.Z }, - //{ GdkKey.?, Key.LWin } - //{ GdkKey.?, Key.RWin } - { GdkKey.Menu, Key.Apps }, - //{ GdkKey.?, Key.Sleep } - { GdkKey.KP_0, Key.NumPad0 }, - { GdkKey.KP_1, Key.NumPad1 }, - { GdkKey.KP_2, Key.NumPad2 }, - { GdkKey.KP_3, Key.NumPad3 }, - { GdkKey.KP_4, Key.NumPad4 }, - { GdkKey.KP_5, Key.NumPad5 }, - { GdkKey.KP_6, Key.NumPad6 }, - { GdkKey.KP_7, Key.NumPad7 }, - { GdkKey.KP_8, Key.NumPad8 }, - { GdkKey.KP_9, Key.NumPad9 }, - { GdkKey.multiply, Key.Multiply }, - { GdkKey.KP_Multiply, Key.Multiply }, - { GdkKey.KP_Add, Key.Add }, - //{ GdkKey.?, Key.Separator } - { GdkKey.KP_Subtract, Key.Subtract }, - { GdkKey.KP_Decimal, Key.Decimal }, - { GdkKey.KP_Divide, Key.Divide }, - { GdkKey.F1, Key.F1 }, - { GdkKey.F2, Key.F2 }, - { GdkKey.F3, Key.F3 }, - { GdkKey.F4, Key.F4 }, - { GdkKey.F5, Key.F5 }, - { GdkKey.F6, Key.F6 }, - { GdkKey.F7, Key.F7 }, - { GdkKey.F8, Key.F8 }, - { GdkKey.F9, Key.F9 }, - { GdkKey.F10, Key.F10 }, - { GdkKey.F11, Key.F11 }, - { GdkKey.F12, Key.F12 }, - { GdkKey.L3, Key.F13 }, - { GdkKey.F14, Key.F14 }, - { GdkKey.L5, Key.F15 }, - { GdkKey.F16, Key.F16 }, - { GdkKey.F17, Key.F17 }, - { GdkKey.L8, Key.F18 }, - { GdkKey.L9, Key.F19 }, - { GdkKey.L10, Key.F20 }, - { GdkKey.R1, Key.F21 }, - { GdkKey.R2, Key.F22 }, - { GdkKey.F23, Key.F23 }, - { GdkKey.R4, Key.F24 }, - { GdkKey.Num_Lock, Key.NumLock }, - { GdkKey.Scroll_Lock, Key.Scroll }, - { GdkKey.Shift_L, Key.LeftShift }, - { GdkKey.Shift_R, Key.RightShift }, - { GdkKey.Control_L, Key.LeftCtrl }, - { GdkKey.Control_R, Key.RightCtrl }, - { GdkKey.Alt_L, Key.LeftAlt }, - { GdkKey.Alt_R, Key.RightAlt }, - //{ GdkKey.?, Key.BrowserBack } - //{ GdkKey.?, Key.BrowserForward } - //{ GdkKey.?, Key.BrowserRefresh } - //{ GdkKey.?, Key.BrowserStop } - //{ GdkKey.?, Key.BrowserSearch } - //{ GdkKey.?, Key.BrowserFavorites } - //{ GdkKey.?, Key.BrowserHome } - //{ GdkKey.?, Key.VolumeMute } - //{ GdkKey.?, Key.VolumeDown } - //{ GdkKey.?, Key.VolumeUp } - //{ GdkKey.?, Key.MediaNextTrack } - //{ GdkKey.?, Key.MediaPreviousTrack } - //{ GdkKey.?, Key.MediaStop } - //{ GdkKey.?, Key.MediaPlayPause } - //{ GdkKey.?, Key.LaunchMail } - //{ GdkKey.?, Key.SelectMedia } - //{ GdkKey.?, Key.LaunchApplication1 } - //{ GdkKey.?, Key.LaunchApplication2 } - { GdkKey.semicolon, Key.OemSemicolon }, - { GdkKey.plus, Key.OemPlus }, - { GdkKey.equal, Key.OemPlus }, - { GdkKey.comma, Key.OemComma }, - { GdkKey.minus, Key.OemMinus }, - { GdkKey.period, Key.OemPeriod }, - { GdkKey.slash, Key.Oem2 }, - { GdkKey.grave, Key.OemTilde }, - //{ GdkKey.?, Key.AbntC1 } - //{ GdkKey.?, Key.AbntC2 } - { GdkKey.bracketleft, Key.OemOpenBrackets }, - { GdkKey.backslash, Key.OemPipe }, - { GdkKey.bracketright, Key.OemCloseBrackets }, - { GdkKey.apostrophe, Key.OemQuotes }, - //{ GdkKey.?, Key.Oem8 } - //{ GdkKey.?, Key.Oem102 } - //{ GdkKey.?, Key.ImeProcessed } - //{ GdkKey.?, Key.System } - //{ GdkKey.?, Key.OemAttn } - //{ GdkKey.?, Key.OemFinish } - //{ GdkKey.?, Key.DbeHiragana } - //{ GdkKey.?, Key.OemAuto } - //{ GdkKey.?, Key.DbeDbcsChar } - //{ GdkKey.?, Key.OemBackTab } - //{ GdkKey.?, Key.Attn } - //{ GdkKey.?, Key.DbeEnterWordRegisterMode } - //{ GdkKey.?, Key.DbeEnterImeConfigureMode } - //{ GdkKey.?, Key.EraseEof } - //{ GdkKey.?, Key.Play } - //{ GdkKey.?, Key.Zoom } - //{ GdkKey.?, Key.NoName } - //{ GdkKey.?, Key.DbeEnterDialogConversionMode } - //{ GdkKey.?, Key.OemClear } - //{ GdkKey.?, Key.DeadCharProcessed } - }; - - public static Key ConvertKey(GdkKey key) - { - Key result; - return KeyDic.TryGetValue(key, out result) ? result : Key.None; - } - } -} diff --git a/src/Gtk/Avalonia.Gtk3/PlatformIconLoader.cs b/src/Gtk/Avalonia.Gtk3/PlatformIconLoader.cs deleted file mode 100644 index 6965e7c812..0000000000 --- a/src/Gtk/Avalonia.Gtk3/PlatformIconLoader.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.IO; -using Avalonia.Gtk3.Interop; -using Avalonia.Platform; - -namespace Avalonia.Gtk3 -{ - class PlatformIconLoader : IPlatformIconLoader - { - public IWindowIconImpl LoadIcon(string fileName) => Pixbuf.NewFromFile(fileName); - - public IWindowIconImpl LoadIcon(Stream stream) => Pixbuf.NewFromStream(stream); - - public IWindowIconImpl LoadIcon(IBitmapImpl bitmap) - { - var ms = new MemoryStream(); - bitmap.Save(ms); - return Pixbuf.NewFromBytes(ms.ToArray()); - } - } -} diff --git a/src/Gtk/Avalonia.Gtk3/PopupImpl.cs b/src/Gtk/Avalonia.Gtk3/PopupImpl.cs deleted file mode 100644 index ef17407dd6..0000000000 --- a/src/Gtk/Avalonia.Gtk3/PopupImpl.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Avalonia.Gtk3.Interop; -using Avalonia.Platform; - -namespace Avalonia.Gtk3 -{ - class PopupImpl : WindowBaseImpl, IPopupImpl - { - static GtkWindow CreateWindow() - { - var window = Native.GtkWindowNew(GtkWindowType.Popup); - return window; - } - - public PopupImpl() : base(CreateWindow()) - { - OverrideRedirect = true; - } - } -} diff --git a/src/Gtk/Avalonia.Gtk3/Properties/AssemblyInfo.cs b/src/Gtk/Avalonia.Gtk3/Properties/AssemblyInfo.cs deleted file mode 100644 index a27d631ee0..0000000000 --- a/src/Gtk/Avalonia.Gtk3/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Reflection; -using Avalonia.Gtk3; -using Avalonia.Platform; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: ExportWindowingSubsystem(OperatingSystemType.WinNT, 2, "GTK3", typeof(Gtk3Platform), nameof(Gtk3Platform.Initialize))] -[assembly: ExportWindowingSubsystem(OperatingSystemType.Linux, 1, "GTK3", typeof(Gtk3Platform), nameof(Gtk3Platform.Initialize))] -[assembly: ExportWindowingSubsystem(OperatingSystemType.OSX, 2, "GTK3", typeof(Gtk3Platform), nameof(Gtk3Platform.Initialize))] \ No newline at end of file diff --git a/src/Gtk/Avalonia.Gtk3/README.md b/src/Gtk/Avalonia.Gtk3/README.md deleted file mode 100644 index ea853bde75..0000000000 --- a/src/Gtk/Avalonia.Gtk3/README.md +++ /dev/null @@ -1,8 +0,0 @@ -P/Invoke based GTK3 backend -=========================== - -Code is EXPERIMENTAL at this point. It also needs Direct2D/Skia for rendering. - -Windows GTK3 binaries aren't included in the repo, you need to download them from https://sourceforge.net/projects/gtk3win/ - -On Linux it should work out of the box with system-provided GTK3. On OSX you should be able to wire GTK3 using DYLD_LIBRARY_PATH environment variable. \ No newline at end of file diff --git a/src/Gtk/Avalonia.Gtk3/ScreenImpl.cs b/src/Gtk/Avalonia.Gtk3/ScreenImpl.cs deleted file mode 100644 index 2cb8a6b127..0000000000 --- a/src/Gtk/Avalonia.Gtk3/ScreenImpl.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Collections.Generic; -using Avalonia.Gtk3.Interop; -using Avalonia.Platform; - -namespace Avalonia.Gtk3 -{ - internal class ScreenImpl : IScreenImpl - { - public int ScreenCount - { - get => _allScreens.Length; - } - - private Screen[] _allScreens; - public IReadOnlyList AllScreens - { - get - { - if (_allScreens == null) - { - IntPtr display = Native.GdkGetDefaultDisplay(); - GdkScreen screen = Native.GdkDisplayGetDefaultScreen(display); - short primary = Native.GdkScreenGetPrimaryMonitor(screen); - Screen[] screens = new Screen[Native.GdkScreenGetNMonitors(screen)]; - for (short i = 0; i < screens.Length; i++) - { - GdkRectangle workArea = new GdkRectangle(), geometry = new GdkRectangle(); - Native.GdkScreenGetMonitorGeometry(screen, i, ref geometry); - Native.GdkScreenGetMonitorWorkarea(screen, i, ref workArea); - PixelRect workAreaRect = new PixelRect(workArea.X, workArea.Y, workArea.Width, workArea.Height); - PixelRect geometryRect = new PixelRect(geometry.X, geometry.Y, geometry.Width, geometry.Height); - GtkScreen s = new GtkScreen(geometryRect, workAreaRect, i == primary, i); - screens[i] = s; - } - - _allScreens = screens; - } - - return _allScreens; - } - } - - public ScreenImpl() - { - IntPtr display = Native.GdkGetDefaultDisplay(); - GdkScreen screen = Native.GdkDisplayGetDefaultScreen(display); - Signal.Connect(screen, "monitors-changed", MonitorsChanged); - } - - private unsafe void MonitorsChanged(IntPtr screen, IntPtr userData) - { - _allScreens = null; - } - } -} diff --git a/src/Gtk/Avalonia.Gtk3/SystemDialogs.cs b/src/Gtk/Avalonia.Gtk3/SystemDialogs.cs deleted file mode 100644 index 1e85eaa156..0000000000 --- a/src/Gtk/Avalonia.Gtk3/SystemDialogs.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Avalonia.Controls; -using Avalonia.Controls.Platform; -using Avalonia.Gtk3.Interop; -using Avalonia.Platform; -using Avalonia.Platform.Interop; - -namespace Avalonia.Gtk3 -{ - class SystemDialogBase - { - - public unsafe static Task ShowDialog(string title, GtkWindow parent, GtkFileChooserAction action, - bool multiselect, string initialFileName, Action 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(); - List disposables = null; - Action dispose = () => - { - // ReSharper disable once PossibleNullReferenceException - foreach (var d in disposables) - d.Dispose(); - disposables.Clear(); - }; - disposables = new List - { - Signal.Connect(dlg, "close", delegate - { - tcs.TrySetResult(null); - dispose(); - return false; - }), - Signal.Connect(dlg, "response", (_, resp, __) => - { - string[] result = null; - if (resp == GtkResponseType.Accept) - { - var rlst = new List(); - 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; - } - - public Task ShowFileDialogAsync(FileDialog dialog, GtkWindow parent, - Action modify = null) - { - return ShowDialog(dialog.Title, parent, - dialog is OpenFileDialog ? GtkFileChooserAction.Open : GtkFileChooserAction.Save, - (dialog as OpenFileDialog)?.AllowMultiple ?? false, - Path.Combine(string.IsNullOrEmpty(dialog.InitialDirectory) ? "" : dialog.InitialDirectory, - string.IsNullOrEmpty(dialog.InitialFileName) ? "" : dialog.InitialFileName), modify); - } - - public async Task ShowFolderDialogAsync(OpenFolderDialog dialog, GtkWindow parent, - Action modify = null) - { - var res = await ShowDialog(dialog.Title, parent, - GtkFileChooserAction.SelectFolder, false, dialog.InitialDirectory, modify); - return res?.FirstOrDefault(); - } - } - - class SystemDialog : SystemDialogBase, ISystemDialogImpl - { - public Task ShowFolderDialogAsync(OpenFolderDialog dialog, IWindowImpl parent) - => ShowFolderDialogAsync(dialog, ((WindowBaseImpl)parent)?.GtkWidget); - - public Task ShowFileDialogAsync(FileDialog dialog, IWindowImpl parent) - => ShowFileDialogAsync(dialog, ((WindowBaseImpl)parent)?.GtkWidget); - } -} diff --git a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs b/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs deleted file mode 100644 index bff50a979d..0000000000 --- a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs +++ /dev/null @@ -1,527 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Threading; -using Avalonia.Controls; -using Avalonia.Gtk3.Interop; -using Avalonia.Input; -using Avalonia.Input.Raw; -using Avalonia.OpenGL; -using Avalonia.Platform; -using Avalonia.Platform.Interop; -using Avalonia.Rendering; -using Avalonia.Threading; - -namespace Avalonia.Gtk3 -{ - abstract class WindowBaseImpl : IWindowBaseImpl, IPlatformHandle, EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo - { - public readonly GtkWindow GtkWidget; - private IInputRoot _inputRoot; - private readonly GtkImContext _imContext; - private readonly FramebufferManager _framebuffer; - private readonly EglGlPlatformSurface _egl; - protected readonly List Disposables = new List(); - private Size _lastSize; - private PixelPoint _lastPosition; - private double _lastScaling; - private uint _lastKbdEvent; - private uint _lastSmoothScrollEvent; - private GCHandle _gcHandle; - private object _lock = new object(); - private IDeferredRenderOperation _nextRenderOperation; - private readonly AutoResetEvent _canSetNextOperation = new AutoResetEvent(true); - internal IntPtr? GdkWindowHandle; - private bool _overrideRedirect; - private uint? _tickCallback; - public WindowBaseImpl(GtkWindow gtkWidget) - { - - GtkWidget = gtkWidget; - - var glf = AvaloniaLocator.Current.GetService() as EglGlPlatformFeature; - if (glf != null) - _egl = new EglGlPlatformSurface((EglDisplay)glf.Display, glf.DeferredContext, this); - else - _framebuffer = new FramebufferManager(this); - - _imContext = Native.GtkImMulticontextNew(); - Disposables.Add(_imContext); - Native.GtkWidgetSetEvents(gtkWidget, 0xFFFFFE); - Disposables.Add(Signal.Connect(_imContext, "commit", OnCommit)); - Connect("draw", OnDraw); - Connect("realize", OnRealized); - ConnectEvent("configure-event", OnConfigured); - ConnectEvent("button-press-event", OnButton); - ConnectEvent("button-release-event", OnButton); - ConnectEvent("motion-notify-event", OnMotion); - ConnectEvent("scroll-event", OnScroll); - ConnectEvent("window-state-event", OnStateChanged); - ConnectEvent("key-press-event", OnKeyEvent); - ConnectEvent("key-release-event", OnKeyEvent); - ConnectEvent("leave-notify-event", OnLeaveNotifyEvent); - ConnectEvent("delete-event", OnClosingEvent); - Connect("destroy", OnDestroy); - Native.GtkWidgetRealize(gtkWidget); - GdkWindowHandle = this.Handle.Handle; - _lastSize = ClientSize; - - if (_egl != null) - Native.GtkWidgetSetDoubleBuffered(gtkWidget, false); - else if (Gtk3Platform.UseDeferredRendering) - { - Native.GtkWidgetSetDoubleBuffered(gtkWidget, false); - _gcHandle = GCHandle.Alloc(this); - _tickCallback = Native.GtkWidgetAddTickCallback(GtkWidget, PinnedStaticCallback, - GCHandle.ToIntPtr(_gcHandle), IntPtr.Zero); - } - } - - private bool OnConfigured(IntPtr gtkwidget, IntPtr ev, IntPtr userdata) - { - int w, h; - if (!OverrideRedirect) - { - Native.GtkWindowGetSize(GtkWidget, out w, out h); - var size = ClientSize = new Size(w, h); - if (_lastSize != size) - { - Resized?.Invoke(size); - _lastSize = size; - } - } - var pos = Position; - if (_lastPosition != pos) - { - PositionChanged?.Invoke(pos); - _lastPosition = pos; - } - var scaling = Scaling; - if (_lastScaling != scaling) - { - ScalingChanged?.Invoke(scaling); - _lastScaling = scaling; - } - return false; - } - - private bool OnRealized(IntPtr gtkwidget, IntPtr userdata) - { - Native.GtkImContextSetClientWindow(_imContext, Native.GtkWidgetGetWindow(GtkWidget)); - return false; - } - - private bool OnDestroy(IntPtr gtkwidget, IntPtr userdata) - { - DoDispose(true); - return false; - } - - private static InputModifiers GetModifierKeys(GdkModifierType state) - { - var rv = InputModifiers.None; - if (state.HasFlag(GdkModifierType.ControlMask)) - rv |= InputModifiers.Control; - if (state.HasFlag(GdkModifierType.ShiftMask)) - rv |= InputModifiers.Shift; - if (state.HasFlag(GdkModifierType.Mod1Mask)) - rv |= InputModifiers.Alt; - if (state.HasFlag(GdkModifierType.Button1Mask)) - rv |= InputModifiers.LeftMouseButton; - if (state.HasFlag(GdkModifierType.Button2Mask)) - rv |= InputModifiers.RightMouseButton; - if (state.HasFlag(GdkModifierType.Button3Mask)) - rv |= InputModifiers.MiddleMouseButton; - return rv; - } - - private unsafe bool OnClosingEvent(IntPtr w, IntPtr ev, IntPtr userdata) - { - bool? preventClosing = Closing?.Invoke(); - return preventClosing ?? false; - } - - private unsafe bool OnButton(IntPtr w, IntPtr ev, IntPtr userdata) - { - var evnt = (GdkEventButton*)ev; - var e = new RawPointerEventArgs( - Gtk3Platform.Mouse, - evnt->time, - _inputRoot, - evnt->type == GdkEventType.ButtonRelease - ? evnt->button == 1 - ? RawPointerEventType.LeftButtonUp - : evnt->button == 3 ? RawPointerEventType.RightButtonUp : RawPointerEventType.MiddleButtonUp - : evnt->button == 1 - ? RawPointerEventType.LeftButtonDown - : evnt->button == 3 ? RawPointerEventType.RightButtonDown : RawPointerEventType.MiddleButtonDown, - new Point(evnt->x, evnt->y), GetModifierKeys(evnt->state)); - OnInput(e); - return true; - } - - protected virtual unsafe bool OnStateChanged(IntPtr w, IntPtr pev, IntPtr userData) - { - var ev = (GdkEventWindowState*) pev; - if (ev->changed_mask.HasFlag(GdkWindowState.Focused)) - { - if(ev->new_window_state.HasFlag(GdkWindowState.Focused)) - Activated?.Invoke(); - else - Deactivated?.Invoke(); - } - return true; - } - - private unsafe bool OnMotion(IntPtr w, IntPtr ev, IntPtr userdata) - { - var evnt = (GdkEventMotion*)ev; - var position = new Point(evnt->x, evnt->y); - Native.GdkEventRequestMotions(ev); - var e = new RawPointerEventArgs( - Gtk3Platform.Mouse, - evnt->time, - _inputRoot, - RawPointerEventType.Move, - position, GetModifierKeys(evnt->state)); - OnInput(e); - - return true; - } - private unsafe bool OnScroll(IntPtr w, IntPtr ev, IntPtr userdata) - { - var evnt = (GdkEventScroll*)ev; - - //Ignore duplicates - if (evnt->time - _lastSmoothScrollEvent < 10 && evnt->direction != GdkScrollDirection.Smooth) - return true; - - var delta = new Vector(); - const double step = (double) 1; - if (evnt->direction == GdkScrollDirection.Down) - delta = new Vector(0, -step); - else if (evnt->direction == GdkScrollDirection.Up) - delta = new Vector(0, step); - else if (evnt->direction == GdkScrollDirection.Right) - delta = new Vector(-step, 0); - else if (evnt->direction == GdkScrollDirection.Left) - delta = new Vector(step, 0); - else if (evnt->direction == GdkScrollDirection.Smooth) - { - delta = new Vector(-evnt->delta_x, -evnt->delta_y); - _lastSmoothScrollEvent = evnt->time; - } - var e = new RawMouseWheelEventArgs(Gtk3Platform.Mouse, evnt->time, _inputRoot, - new Point(evnt->x, evnt->y), delta, GetModifierKeys(evnt->state)); - OnInput(e); - return true; - } - - private unsafe bool OnKeyEvent(IntPtr w, IntPtr pev, IntPtr userData) - { - var evnt = (GdkEventKey*) pev; - _lastKbdEvent = evnt->time; - var e = new RawKeyEventArgs( - Gtk3Platform.Keyboard, - evnt->time, - evnt->type == GdkEventType.KeyPress ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp, - Avalonia.Gtk.Common.KeyTransform.ConvertKey((GdkKey)evnt->keyval), GetModifierKeys((GdkModifierType)evnt->state)); - OnInput(e); - if (Native.GtkImContextFilterKeypress(_imContext, pev)) - return true; - return true; - } - - private unsafe bool OnLeaveNotifyEvent(IntPtr w, IntPtr pev, IntPtr userData) - { - var evnt = (GdkEventCrossing*) pev; - var position = new Point(evnt->x, evnt->y); - OnInput(new RawPointerEventArgs(Gtk3Platform.Mouse, - evnt->time, - _inputRoot, - RawPointerEventType.Move, - position, GetModifierKeys(evnt->state))); - return true; - } - - private unsafe bool OnCommit(IntPtr gtkwidget, IntPtr utf8string, IntPtr userdata) - { - OnInput(new RawTextInputEventArgs(Gtk3Platform.Keyboard, _lastKbdEvent, Utf8Buffer.StringFromPtr(utf8string))); - return true; - } - - protected void ConnectEvent(string name, Native.D.signal_onevent handler) - => Disposables.Add(Signal.Connect(GtkWidget, name, handler)); - void Connect(string name, T handler) => Disposables.Add(Signal.Connect(GtkWidget, name, handler)); - - internal IntPtr CurrentCairoContext { get; private set; } - - private bool OnDraw(IntPtr gtkwidget, IntPtr cairocontext, IntPtr userdata) - { - if (!Gtk3Platform.UseDeferredRendering) - { - CurrentCairoContext = cairocontext; - Paint?.Invoke(new Rect(ClientSize)); - CurrentCairoContext = IntPtr.Zero; - } - else - Paint?.Invoke(new Rect(ClientSize)); - return true; - } - - private static Native.D.TickCallback PinnedStaticCallback = StaticTickCallback; - - static bool StaticTickCallback(IntPtr widget, IntPtr clock, IntPtr userData) - { - var impl = (WindowBaseImpl) GCHandle.FromIntPtr(userData).Target; - impl.OnRenderTick(); - return true; - } - - public void SetNextRenderOperation(IDeferredRenderOperation op) - { - while (true) - { - lock (_lock) - { - if (_nextRenderOperation == null) - { - _nextRenderOperation = op; - return; - } - } - _canSetNextOperation.WaitOne(); - } - - } - - private void OnRenderTick() - { - IDeferredRenderOperation op = null; - lock (_lock) - { - if (_nextRenderOperation != null) - { - op = _nextRenderOperation; - _nextRenderOperation = null; - } - _canSetNextOperation.Set(); - } - if (op != null) - { - op?.RenderNow(null); - op?.Dispose(); - } - } - - - public void Dispose() => DoDispose(false); - - void DoDispose(bool fromDestroy) - { - if (_tickCallback.HasValue) - { - if (!GtkWidget.IsClosed) - Native.GtkWidgetRemoveTickCallback(GtkWidget, _tickCallback.Value); - _tickCallback = null; - } - - //We are calling it here, since signal handler will be detached - if (!GtkWidget.IsClosed) - Closed?.Invoke(); - foreach(var d in Disposables.AsEnumerable().Reverse()) - d.Dispose(); - Disposables.Clear(); - - if (!fromDestroy && !GtkWidget.IsClosed) - Native.GtkWindowClose(GtkWidget); - GtkWidget.Dispose(); - - if (_gcHandle.IsAllocated) - { - _gcHandle.Free(); - } - } - - public Size MaxClientSize - { - get - { - var s = Native.GtkWidgetGetScreen(GtkWidget); - return new Size(Native.GdkScreenGetWidth(s), Native.GdkScreenGetHeight(s)); - } - } - - public void SetMinMaxSize(Size minSize, Size maxSize) - { - if (GtkWidget.IsClosed) - return; - - GdkGeometry geometry = new GdkGeometry(); - geometry.min_width = minSize.Width > 0 ? (int)minSize.Width : -1; - geometry.min_height = minSize.Height > 0 ? (int)minSize.Height : -1; - geometry.max_width = !Double.IsInfinity(maxSize.Width) && maxSize.Width > 0 ? (int)maxSize.Width : 999999; - geometry.max_height = !Double.IsInfinity(maxSize.Height) && maxSize.Height > 0 ? (int)maxSize.Height : 999999; - - Native.GtkWindowSetGeometryHints(GtkWidget, IntPtr.Zero, ref geometry, GdkWindowHints.GDK_HINT_MIN_SIZE | GdkWindowHints.GDK_HINT_MAX_SIZE); - } - - public IMouseDevice MouseDevice => Gtk3Platform.Mouse; - - public double Scaling => LastKnownScaleFactor = (int) (Native.GtkWidgetGetScaleFactor?.Invoke(GtkWidget) ?? 1); - - public IPlatformHandle Handle => this; - - string IPlatformHandle.HandleDescriptor => "HWND"; - - public Action Activated { get; set; } - public Func Closing { get; set; } - public Action Closed { get; set; } - public Action Deactivated { get; set; } - public Action Input { get; set; } - public Action Paint { get; set; } - public Action Resized { get; set; } - public Action ScalingChanged { get; set; } //TODO - public Action PositionChanged { get; set; } - - public void Activate() => Native.GtkWidgetActivate(GtkWidget); - - public void Invalidate(Rect rect) - { - if(GtkWidget.IsClosed) - return; - var s = ClientSize; - Native.GtkWidgetQueueDrawArea(GtkWidget, 0, 0, (int) s.Width, (int) s.Height); - } - - public void SetInputRoot(IInputRoot inputRoot) => _inputRoot = inputRoot; - - void OnInput(RawInputEventArgs args) - { - Dispatcher.UIThread.Post(() => Input?.Invoke(args), DispatcherPriority.Input); - } - - public Point PointToClient(PixelPoint point) - { - int x, y; - Native.GdkWindowGetOrigin(Native.GtkWidgetGetWindow(GtkWidget), out x, out y); - - return new Point(point.X - x, point.Y - y); - } - - public PixelPoint PointToScreen(Point point) - { - int x, y; - Native.GdkWindowGetOrigin(Native.GtkWidgetGetWindow(GtkWidget), out x, out y); - return new PixelPoint((int)(point.X + x), (int)(point.Y + y)); - } - - public void SetCursor(IPlatformHandle cursor) - { - if (GtkWidget.IsClosed) - return; - Native.GdkWindowSetCursor(Native.GtkWidgetGetWindow(GtkWidget), cursor?.Handle ?? IntPtr.Zero); - } - - public virtual void Show() => Native.GtkWindowPresent(GtkWidget); - - public void Hide() => Native.GtkWidgetHide(GtkWidget); - - public void SetTopmost(bool value) => Native.GtkWindowSetKeepAbove(GtkWidget, value); - - void GetGlobalPointer(out int x, out int y) - { - int mask; - Native.GdkWindowGetPointer(Native.GdkScreenGetRootWindow(Native.GtkWidgetGetScreen(GtkWidget)), - out x, out y, out mask); - } - - public void BeginMoveDrag() - { - int x, y; - GetGlobalPointer(out x, out y); - Native.GdkWindowBeginMoveDrag(Native.GtkWidgetGetWindow(GtkWidget), 1, x, y, 0); - } - - public void BeginResizeDrag(WindowEdge edge) - { - int x, y; - GetGlobalPointer(out x, out y); - Native.GdkWindowBeginResizeDrag(Native.GtkWidgetGetWindow(GtkWidget), edge, 1, x, y, 0); - } - - - public Size ClientSize { get; private set; } - public int LastKnownScaleFactor { get; private set; } - - public void Resize(Size value) - { - if (GtkWidget.IsClosed) - return; - - Native.GtkWindowResize(GtkWidget, (int)value.Width, (int)value.Height); - if (OverrideRedirect) - { - var size = ClientSize = value; - if (_lastSize != size) - { - Resized?.Invoke(size); - _lastSize = size; - } - } - } - - public bool OverrideRedirect - { - get => _overrideRedirect; - set - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - Native.GdkWindowSetOverrideRedirect(Native.GtkWidgetGetWindow(GtkWidget), value); - _overrideRedirect = value; - } - } - } - - public IScreenImpl Screen - { - get; - } = new ScreenImpl(); - - public PixelPoint Position - { - get - { - int x, y; - Native.GtkWindowGetPosition(GtkWidget, out x, out y); - return new PixelPoint(x, y); - } - set { Native.GtkWindowMove(GtkWidget, (int)value.X, (int)value.Y); } - } - - IntPtr IPlatformHandle.Handle => Native.GetNativeGdkWindowHandle(Native.GtkWidgetGetWindow(GtkWidget)); - public IEnumerable Surfaces => new object[] {Handle, _egl, _framebuffer}; - - public IRenderer CreateRenderer(IRenderRoot root) - { - var loop = AvaloniaLocator.Current.GetService(); - return Gtk3Platform.UseDeferredRendering - ? (IRenderer) new DeferredRenderer(root, loop) - : new ImmediateRenderer(root); - } - - PixelSize EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo.Size - { - get - { - var cs = ClientSize; - return new PixelSize((int)Math.Max(1, LastKnownScaleFactor * cs.Width), - (int)Math.Max(1, LastKnownScaleFactor * ClientSize.Height)); - } - } - double EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo.Scaling => LastKnownScaleFactor; - IntPtr EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo.Handle => Handle.Handle; - } -} diff --git a/src/Gtk/Avalonia.Gtk3/WindowImpl.cs b/src/Gtk/Avalonia.Gtk3/WindowImpl.cs deleted file mode 100644 index 1c8d800f2f..0000000000 --- a/src/Gtk/Avalonia.Gtk3/WindowImpl.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using Avalonia.Controls; -using Avalonia.Gtk3.Interop; -using Avalonia.Platform; -using Avalonia.Platform.Interop; - -namespace Avalonia.Gtk3 -{ - class WindowImpl : WindowBaseImpl, IWindowImpl - { - private WindowState _lastWindowState; - - public WindowImpl() : base(Native.GtkWindowNew(GtkWindowType.TopLevel)) - { - } - - protected unsafe override bool OnStateChanged(IntPtr w, IntPtr pev, IntPtr userData) - { - var windowStateEvent = (GdkEventWindowState*)pev; - var newWindowState = windowStateEvent->new_window_state; - var windowState = newWindowState.HasFlag(GdkWindowState.Iconified) ? WindowState.Minimized - : (newWindowState.HasFlag(GdkWindowState.Maximized) ? WindowState.Maximized : WindowState.Normal); - - if (windowState != _lastWindowState) - { - _lastWindowState = windowState; - WindowStateChanged?.Invoke(windowState); - } - - return base.OnStateChanged(w, pev, userData); - } - - public void SetTitle(string title) - { - using (var t = new Utf8Buffer(title)) - Native.GtkWindowSetTitle(GtkWidget, t); - } - - public WindowState WindowState - { - get - { - var state = Native.GdkWindowGetState(Native.GtkWidgetGetWindow(GtkWidget)); - if (state.HasFlag(GdkWindowState.Iconified)) - return WindowState.Minimized; - if (state.HasFlag(GdkWindowState.Maximized)) - return WindowState.Maximized; - return WindowState.Normal; - } - set - { - if (value == WindowState.Minimized) - Native.GtkWindowIconify(GtkWidget); - else if (value == WindowState.Maximized) - Native.GtkWindowMaximize(GtkWidget); - else - { - Native.GtkWindowUnmaximize(GtkWidget); - Native.GtkWindowDeiconify(GtkWidget); - } - } - } - - public Action WindowStateChanged { get; set; } - - public void ShowDialog(IWindowImpl parent) - { - Native.GtkWindowSetModal(GtkWidget, true); - Native.GtkWindowSetTransientFor(GtkWidget, ((WindowImpl)parent).GtkWidget.DangerousGetHandle()); - Native.GtkWindowPresent(GtkWidget); - } - - public override void Show() - { - Native.GtkWindowSetModal(GtkWidget, false); - Native.GtkWindowSetTransientFor(GtkWidget, IntPtr.Zero); - Native.GtkWindowPresent(GtkWidget); - } - - public void SetSystemDecorations(bool enabled) => Native.GtkWindowSetDecorated(GtkWidget, enabled); - - public void SetIcon(IWindowIconImpl icon) => Native.GtkWindowSetIcon(GtkWidget, (Pixbuf) icon); - - public void SetCoverTaskbarWhenMaximized(bool enable) - { - //Why do we even have that? - } - - public void ShowTaskbarIcon(bool value) => Native.GtkWindowSetSkipTaskbarHint(GtkWidget, !value); - - public void CanResize(bool value) => Native.GtkWindowSetResizable(GtkWidget, value); - - - class EmptyDisposable : IDisposable - { - public void Dispose() - { - - } - } - } -} diff --git a/src/Gtk/Avalonia.Gtk3/X11.cs b/src/Gtk/Avalonia.Gtk3/X11.cs deleted file mode 100644 index 4677114bdb..0000000000 --- a/src/Gtk/Avalonia.Gtk3/X11.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Avalonia.Gtk3 -{ - class X11 - { - [DllImport("libX11.so.6")] - public static extern IntPtr XInitThreads(); - - [DllImport("libX11.so.6")] - public static extern IntPtr XOpenDisplay(IntPtr name); - - [DllImport("libX11.so.6")] - public static extern IntPtr XLockDisplay(IntPtr display); - - [DllImport("libX11.so.6")] - public static extern IntPtr XUnlockDisplay(IntPtr display); - - [DllImport("libX11.so.6")] - public static extern IntPtr XFreeGC(IntPtr display, IntPtr gc); - - [DllImport("libX11.so.6")] - public static extern IntPtr XCreateGC(IntPtr display, IntPtr drawable, ulong valuemask, IntPtr values); - - [DllImport("libX11.so.6")] - public static extern int XInitImage(ref XImage image); - - [DllImport("libX11.so.6")] - public static extern int XDestroyImage(ref XImage image); - - [DllImport("libX11.so.6")] - public static extern IntPtr XSetErrorHandler(XErrorHandler handler); - - [DllImport("libX11.so.6")] - public static extern int XSync(IntPtr display, bool discard); - - public delegate int XErrorHandler(IntPtr display, ref XErrorEvent error); - - [DllImport("libX11.so.6")] - public static extern int XPutImage(IntPtr display, IntPtr drawable, IntPtr gc, ref XImage image, - int srcx, int srcy, int destx, int desty, uint width, uint height); - - [StructLayout(LayoutKind.Sequential)] - public unsafe struct XErrorEvent - { - public int type; - public IntPtr* display; /* Display the event was read from */ - public ulong serial; /* serial number of failed request */ - public byte error_code; /* error code of failed request */ - public byte request_code; /* Major op-code of failed request */ - public byte minor_code; /* Minor op-code of failed request */ - public IntPtr resourceid; /* resource id */ - } - - [StructLayout(LayoutKind.Sequential)] - public unsafe struct XImage - { - public int width, height; /* size of image */ - public int xoffset; /* number of pixels offset in X direction */ - public int format; /* XYBitmap, XYPixmap, ZPixmap */ - public IntPtr data; /* pointer to image data */ - public int byte_order; /* data byte order, LSBFirst, MSBFirst */ - public int bitmap_unit; /* quant. of scanline 8, 16, 32 */ - public int bitmap_bit_order; /* LSBFirst, MSBFirst */ - public int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */ - public int depth; /* depth of image */ - public int bytes_per_line; /* accelerator to next scanline */ - public int bits_per_pixel; /* bits per pixel (ZPixmap) */ - public ulong red_mask; /* bits in z arrangement */ - public ulong green_mask; - public ulong blue_mask; - private fixed byte funcs[128]; - } - - - } -} \ No newline at end of file diff --git a/src/Gtk/Avalonia.Gtk3/X11Framebuffer.cs b/src/Gtk/Avalonia.Gtk3/X11Framebuffer.cs deleted file mode 100644 index c84d7c7541..0000000000 --- a/src/Gtk/Avalonia.Gtk3/X11Framebuffer.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using Avalonia.Platform; - -namespace Avalonia.Gtk3 -{ - class X11Framebuffer : ILockedFramebuffer - { - private readonly IntPtr _display; - private readonly IntPtr _xid; - private IUnmanagedBlob _blob; - - public X11Framebuffer(IntPtr display, IntPtr xid, int width, int height, int factor) - { - _display = display; - _xid = xid; - Size = new PixelSize(width * factor, height * factor); - RowBytes = Size.Width * 4; - Dpi = new Vector(96, 96) * factor; - Format = PixelFormat.Bgra8888; - _blob = AvaloniaLocator.Current.GetService().AllocBlob(RowBytes * Size.Height); - Address = _blob.Address; - } - - public void Dispose() - { - var image = new X11.XImage(); - int bitsPerPixel = 32; - image.width = Size.Width; - image.height = Size.Height; - image.format = 2; //ZPixmap; - image.data = Address; - image.byte_order = 0;// LSBFirst; - image.bitmap_unit = bitsPerPixel; - image.bitmap_bit_order = 0;// LSBFirst; - image.bitmap_pad = bitsPerPixel; - image.depth = 24; - image.bytes_per_line = RowBytes - Size.Width * 4; - image.bits_per_pixel = bitsPerPixel; - X11.XLockDisplay(_display); - X11.XInitImage(ref image); - var gc = X11.XCreateGC(_display, _xid, 0, IntPtr.Zero); - X11.XPutImage(_display, _xid, gc, ref image, 0, 0, 0, 0, (uint)Size.Width, (uint)Size.Height); - X11.XFreeGC(_display, gc); - X11.XSync(_display, true); - X11.XUnlockDisplay(_display); - _blob.Dispose(); - } - - public IntPtr Address { get; } - public PixelSize Size { get; } - public int RowBytes { get; } - public Vector Dpi { get; } - public PixelFormat Format { get; } - } -} From e4c0ecc0e35f3f070d8e2539d74a27623d8cfc82 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Mon, 24 Jun 2019 00:51:27 +1000 Subject: [PATCH 11/11] Make Avalonia compile on windows machines with VS2017 and VS2019 --- nukebuild/Build.cs | 28 +++++++++++++++++++++++----- nukebuild/_build.csproj | 3 ++- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/nukebuild/Build.cs b/nukebuild/Build.cs index 84092d52eb..a99ac4d026 100644 --- a/nukebuild/Build.cs +++ b/nukebuild/Build.cs @@ -19,7 +19,7 @@ using static Nuke.Common.IO.PathConstruction; using static Nuke.Common.Tools.MSBuild.MSBuildTasks; using static Nuke.Common.Tools.DotNet.DotNetTasks; using static Nuke.Common.Tools.Xunit.XunitTasks; - +using static Nuke.Common.Tools.VSWhere.VSWhereTasks; /* Before editing this file, install support plugin for your IDE, @@ -30,7 +30,26 @@ using static Nuke.Common.Tools.Xunit.XunitTasks; */ partial class Build : NukeBuild -{ +{ + static Lazy MsBuildExe = new Lazy(() => + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + return null; + + var msBuildDirectory = VSWhere("-latest -nologo -property installationPath -format value -prerelease").FirstOrDefault().Text; + + if (!string.IsNullOrWhiteSpace(msBuildDirectory)) + { + string msBuildExe = Path.Combine(msBuildDirectory, @"MSBuild\Current\Bin\MSBuild.exe"); + if (!System.IO.File.Exists(msBuildExe)) + msBuildExe = Path.Combine(msBuildDirectory, @"MSBuild\15.0\Bin\MSBuild.exe"); + + return msBuildExe; + } + + return null; + }, false); + BuildParameters Parameters { get; set; } protected override void OnBuildInitialized() { @@ -85,7 +104,6 @@ partial class Build : NukeBuild .DependsOn(Clean) .Executes(() => { - if (Parameters.IsRunningOnWindows) MSBuild(Parameters.MSBuildSolution, c => c .SetArgumentConfigurator(a => a.Add("/r")) @@ -93,7 +111,7 @@ partial class Build : NukeBuild .SetVerbosity(MSBuildVerbosity.Minimal) .AddProperty("PackageVersion", Parameters.Version) .AddProperty("iOSRoslynPathHackRequired", "true") - .SetToolsVersion(MSBuildToolsVersion._15_0) + .SetToolPath(MsBuildExe.Value) .AddTargets("Build") ); @@ -224,7 +242,7 @@ partial class Build : NukeBuild .SetVerbosity(MSBuildVerbosity.Minimal) .AddProperty("PackageVersion", Parameters.Version) .AddProperty("iOSRoslynPathHackRequired", "true") - .SetToolsVersion(MSBuildToolsVersion._15_0) + .SetToolPath(MsBuildExe.Value) .AddTargets("Pack")); else DotNetPack(Parameters.MSBuildSolution, c => diff --git a/nukebuild/_build.csproj b/nukebuild/_build.csproj index e02acff007..2a736e4653 100644 --- a/nukebuild/_build.csproj +++ b/nukebuild/_build.csproj @@ -1,4 +1,4 @@ - + Exe @@ -13,6 +13,7 @@ +