From e00f0f0385ad1b1aa3fd48f036e7730b36fa6fa2 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 13 Oct 2018 12:04:05 +0300 Subject: [PATCH 1/3] Platform-specific key gestures --- .../Avalonia.Android/AndroidPlatform.cs | 1 + src/Avalonia.Controls/TextBox.cs | 363 ++++++++++-------- src/Avalonia.Input/Key.cs | 18 + src/Avalonia.Input/KeyGesture.cs | 11 + .../Platform/PlatformHotkeyConfiguration.cs | 94 +++++ src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs | 1 + .../LinuxFramebufferPlatform.cs | 2 + src/OSX/Avalonia.MonoMac/MonoMacPlatform.cs | 1 + src/Windows/Avalonia.Win32/Win32Platform.cs | 1 + src/iOS/Avalonia.iOS/iOSPlatform.cs | 1 + .../Avalonia.UnitTests/UnitTestApplication.cs | 2 + 11 files changed, 340 insertions(+), 155 deletions(-) create mode 100644 src/Avalonia.Input/Platform/PlatformHotkeyConfiguration.cs diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs index 5f0edadf63..4e48811c35 100644 --- a/src/Android/Avalonia.Android/AndroidPlatform.cs +++ b/src/Android/Avalonia.Android/AndroidPlatform.cs @@ -54,6 +54,7 @@ namespace Avalonia.Android .Bind().ToSingleton() .Bind().ToConstant(new DefaultRenderTimer(60)) .Bind().ToConstant(new RenderLoop()) + .Bind().ToSingleton() .Bind().ToConstant(new AssetLoader(app.GetType().Assembly)); SkiaPlatform.Initialize(); diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index e2d2f562ec..56c5129275 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -368,186 +368,239 @@ namespace Avalonia.Controls string text = Text ?? string.Empty; int caretIndex = CaretIndex; bool movement = false; + bool selection = false; bool handled = false; var modifiers = e.Modifiers; - switch (e.Key) - { - case Key.A: - if (modifiers == InputModifiers.Control) - { - SelectAll(); - handled = true; - } - break; - case Key.C: - if (modifiers == InputModifiers.Control) - { - if (!IsPasswordBox) - { - Copy(); - } - handled = true; - } - break; + var keymap = AvaloniaLocator.Current.GetService(); - case Key.X: - if (modifiers == InputModifiers.Control) - { - if (!IsPasswordBox) - { - Copy(); - DeleteSelection(); - } - handled = true; - } - break; + bool Match(List gestures) => gestures.Any(g => g.Matches(e)); + bool DetectSelection() => e.Modifiers.HasFlag(keymap.SelectionModifiers); - case Key.V: - if (modifiers == InputModifiers.Control) - { - Paste(); - handled = true; - } + if (Match(keymap.SelectAll)) + { + SelectAll(); + handled = true; + } + else if (Match(keymap.Copy)) + { + if (!IsPasswordBox) + { + Copy(); + } - break; + handled = true; + } + else if (Match(keymap.Cut)) + { + if (!IsPasswordBox) + { + Copy(); + DeleteSelection(); + } - case Key.Z: - if (modifiers == InputModifiers.Control) - { - try - { - _isUndoingRedoing = true; - _undoRedoHelper.Undo(); - } - finally - { - _isUndoingRedoing = false; - } - handled = true; - } - break; - case Key.Y: - if (modifiers == InputModifiers.Control) - { - try - { - _isUndoingRedoing = true; - _undoRedoHelper.Redo(); - } - finally - { - _isUndoingRedoing = false; - } - handled = true; - } - break; - case Key.Left: - MoveHorizontal(-1, modifiers); - movement = true; - break; + handled = true; + } + else if (Match(keymap.Paste)) + { - case Key.Right: - MoveHorizontal(1, modifiers); - movement = true; - break; + Paste(); + handled = true; + } + else if (Match(keymap.Undo)) + { - case Key.Up: - movement = MoveVertical(-1, modifiers); - break; + try + { + _isUndoingRedoing = true; + _undoRedoHelper.Undo(); + } + finally + { + _isUndoingRedoing = false; + } - case Key.Down: - movement = MoveVertical(1, modifiers); - break; + handled = true; + } + else if (Match(keymap.Redo)) + { + try + { + _isUndoingRedoing = true; + _undoRedoHelper.Redo(); + } + finally + { + _isUndoingRedoing = false; + } - case Key.Home: - MoveHome(modifiers); - movement = true; - break; + handled = true; + } + else if (Match(keymap.MoveCursorToTheStartOfDocument)) + { + MoveHome(true); + movement = true; + selection = false; + handled = true; + } + else if (Match(keymap.MoveCursorToTheEndOfDocument)) + { + MoveEnd(true); + movement = true; + selection = false; + handled = true; + } + else if (Match(keymap.MoveCursorToTheStartOfLine)) + { + MoveHome(false); + movement = true; + selection = false; + handled = true; + + } + else if (Match(keymap.MoveCursorToTheEndOfLine)) + { + MoveEnd(false); + movement = true; + selection = false; + handled = true; + } + else if (Match(keymap.MoveCursorToTheStartOfDocumentWithSelection)) + { + MoveHome(true); + movement = true; + selection = true; + handled = true; + } + else if (Match(keymap.MoveCursorToTheEndOfDocumentWithSelection)) + { + MoveEnd(true); + movement = true; + selection = true; + handled = true; + } + else if (Match(keymap.MoveCursorToTheStartOfLineWithSelection)) + { + MoveHome(false); + movement = true; + selection = true; + handled = true; + + } + else if (Match(keymap.MoveCursorToTheEndOfLineWithSelection)) + { + MoveEnd(false); + movement = true; + selection = true; + handled = true; + } + else + switch (e.Key) + { + case Key.Left: + MoveHorizontal(-1, modifiers); + movement = true; + selection = DetectSelection(); + break; - case Key.End: - MoveEnd(modifiers); - movement = true; - break; + case Key.Right: + MoveHorizontal(1, modifiers); + movement = true; + selection = DetectSelection(); + break; - case Key.Back: - if (modifiers == InputModifiers.Control && SelectionStart == SelectionEnd) - { - SetSelectionForControlBackspace(modifiers); - } + case Key.Up: + movement = MoveVertical(-1, modifiers); + selection = DetectSelection(); + break; - if (!DeleteSelection() && CaretIndex > 0) - { - var removedCharacters = 1; - // handle deleting /r/n - // you don't ever want to leave a dangling /r around. So, if deleting /n, check to see if - // a /r should also be deleted. - if (CaretIndex > 1 && - text[CaretIndex - 1] == '\n' && - text[CaretIndex - 2] == '\r') + case Key.Down: + movement = MoveVertical(1, modifiers); + selection = DetectSelection(); + break; + + case Key.Back: + if (modifiers == keymap.CommandModifiers && SelectionStart == SelectionEnd) { - removedCharacters = 2; + SetSelectionForControlBackspace(modifiers); } - SetTextInternal(text.Substring(0, caretIndex - removedCharacters) + text.Substring(caretIndex)); - CaretIndex -= removedCharacters; - SelectionStart = SelectionEnd = CaretIndex; - } - handled = true; - break; + if (!DeleteSelection() && CaretIndex > 0) + { + var removedCharacters = 1; + // handle deleting /r/n + // you don't ever want to leave a dangling /r around. So, if deleting /n, check to see if + // a /r should also be deleted. + if (CaretIndex > 1 && + text[CaretIndex - 1] == '\n' && + text[CaretIndex - 2] == '\r') + { + removedCharacters = 2; + } - case Key.Delete: - if (modifiers == InputModifiers.Control && SelectionStart == SelectionEnd) - { - SetSelectionForControlDelete(modifiers); - } + SetTextInternal(text.Substring(0, caretIndex - removedCharacters) + + text.Substring(caretIndex)); + CaretIndex -= removedCharacters; + SelectionStart = SelectionEnd = CaretIndex; + } - if (!DeleteSelection() && caretIndex < text.Length) - { - var removedCharacters = 1; - // handle deleting /r/n - // you don't ever want to leave a dangling /r around. So, if deleting /n, check to see if - // a /r should also be deleted. - if (CaretIndex < text.Length - 1 && - text[caretIndex + 1] == '\n' && - text[caretIndex] == '\r') + handled = true; + break; + + case Key.Delete: + if (modifiers == keymap.CommandModifiers && SelectionStart == SelectionEnd) { - removedCharacters = 2; + SetSelectionForControlDelete(modifiers); } - SetTextInternal(text.Substring(0, caretIndex) + text.Substring(caretIndex + removedCharacters)); - } - handled = true; - break; + if (!DeleteSelection() && caretIndex < text.Length) + { + var removedCharacters = 1; + // handle deleting /r/n + // you don't ever want to leave a dangling /r around. So, if deleting /n, check to see if + // a /r should also be deleted. + if (CaretIndex < text.Length - 1 && + text[caretIndex + 1] == '\n' && + text[caretIndex] == '\r') + { + removedCharacters = 2; + } + + SetTextInternal(text.Substring(0, caretIndex) + + text.Substring(caretIndex + removedCharacters)); + } - case Key.Enter: - if (AcceptsReturn) - { - HandleTextInput(NewLine); handled = true; - } + break; - break; + case Key.Enter: + if (AcceptsReturn) + { + HandleTextInput(NewLine); + handled = true; + } - case Key.Tab: - if (AcceptsTab) - { - HandleTextInput("\t"); - handled = true; - } - else - { - base.OnKeyDown(e); - } + break; - break; + case Key.Tab: + if (AcceptsTab) + { + HandleTextInput("\t"); + handled = true; + } + else + { + base.OnKeyDown(e); + } - default: - handled = false; - break; - } + break; + + default: + handled = false; + break; + } - if (movement && ((modifiers & InputModifiers.Shift) != 0)) + if (movement && selection) { SelectionEnd = CaretIndex; } @@ -732,12 +785,12 @@ namespace Avalonia.Controls } } - private void MoveHome(InputModifiers modifiers) + private void MoveHome(bool document) { var text = Text ?? string.Empty; var caretIndex = CaretIndex; - if ((modifiers & InputModifiers.Control) != 0) + if (document) { caretIndex = 0; } @@ -762,12 +815,12 @@ namespace Avalonia.Controls CaretIndex = caretIndex; } - private void MoveEnd(InputModifiers modifiers) + private void MoveEnd(bool document) { var text = Text ?? string.Empty; var caretIndex = CaretIndex; - if ((modifiers & InputModifiers.Control) != 0) + if (document) { caretIndex = text.Length; } diff --git a/src/Avalonia.Input/Key.cs b/src/Avalonia.Input/Key.cs index d4f95dbd5c..d51b990fd4 100644 --- a/src/Avalonia.Input/Key.cs +++ b/src/Avalonia.Input/Key.cs @@ -1020,5 +1020,23 @@ namespace Avalonia.Input /// The key is used with another key to create a single combined character. /// DeadCharProcessed = 172, + + + /// + /// OSX Platform-specific Fn+Left key + /// + FnLeftArrow = 10001, + /// + /// OSX Platform-specific Fn+Right key + /// + FnRightArrow = 10002, + /// + /// OSX Platform-specific Fn+Up key + /// + FnUpArrow = 10003, + /// + /// OSX Platform-specific Fn+Down key + /// + FnDownArrow = 10004, } } diff --git a/src/Avalonia.Input/KeyGesture.cs b/src/Avalonia.Input/KeyGesture.cs index bb3b15c64f..c945902def 100644 --- a/src/Avalonia.Input/KeyGesture.cs +++ b/src/Avalonia.Input/KeyGesture.cs @@ -6,6 +6,17 @@ namespace Avalonia.Input { public sealed class KeyGesture : IEquatable { + public KeyGesture() + { + + } + + public KeyGesture(Key key, InputModifiers modifiers = InputModifiers.None) + { + Key = key; + Modifiers = modifiers; + } + public bool Equals(KeyGesture other) { if (ReferenceEquals(null, other)) return false; diff --git a/src/Avalonia.Input/Platform/PlatformHotkeyConfiguration.cs b/src/Avalonia.Input/Platform/PlatformHotkeyConfiguration.cs new file mode 100644 index 0000000000..5f3093df78 --- /dev/null +++ b/src/Avalonia.Input/Platform/PlatformHotkeyConfiguration.cs @@ -0,0 +1,94 @@ +using System.Collections.Generic; + +namespace Avalonia.Input.Platform +{ + public class PlatformHotkeyConfiguration + { + public PlatformHotkeyConfiguration() : this(InputModifiers.Control) + { + + } + + public PlatformHotkeyConfiguration(InputModifiers commandModifiers, InputModifiers selectionModifiers = InputModifiers.Shift) + { + CommandModifiers = commandModifiers; + SelectionModifiers = selectionModifiers; + Copy = new List + { + new KeyGesture(Key.C, commandModifiers) + }; + Cut = new List + { + new KeyGesture(Key.X, commandModifiers) + }; + Paste = new List + { + new KeyGesture(Key.V, commandModifiers) + }; + Undo = new List + { + new KeyGesture(Key.Z, commandModifiers) + }; + Redo = new List + { + new KeyGesture(Key.Y, commandModifiers), + new KeyGesture(Key.Z, commandModifiers | selectionModifiers) + }; + SelectAll = new List + { + new KeyGesture(Key.A, commandModifiers) + }; + MoveCursorToTheStartOfLine = new List + { + new KeyGesture(Key.Home) + }; + MoveCursorToTheEndOfLine = new List + { + new KeyGesture(Key.End) + }; + MoveCursorToTheStartOfDocument = new List + { + new KeyGesture(Key.Home, commandModifiers) + }; + MoveCursorToTheEndOfDocument = new List + { + new KeyGesture(Key.End, commandModifiers) + }; + MoveCursorToTheStartOfLineWithSelection = new List + { + new KeyGesture(Key.Home, selectionModifiers) + }; + MoveCursorToTheEndOfLineWithSelection = new List + { + new KeyGesture(Key.End, selectionModifiers) + }; + MoveCursorToTheStartOfDocumentWithSelection = new List + { + new KeyGesture(Key.Home, commandModifiers | selectionModifiers) + }; + MoveCursorToTheEndOfDocumentWithSelection = new List + { + new KeyGesture(Key.End, commandModifiers | selectionModifiers) + }; + } + + public InputModifiers CommandModifiers { get; set; } + public InputModifiers SelectionModifiers { get; set; } + public List Copy { get; set; } + public List Cut { get; set; } + public List Paste { get; set; } + public List Undo { get; set; } + public List Redo { get; set; } + public List SelectAll { get; set; } + public List MoveCursorToTheStartOfLine { get; set; } + public List MoveCursorToTheEndOfLine { get; set; } + public List MoveCursorToTheStartOfDocument { get; set; } + public List MoveCursorToTheEndOfDocument { get; set; } + public List MoveCursorToTheStartOfLineWithSelection { get; set; } + public List MoveCursorToTheEndOfLineWithSelection { get; set; } + public List MoveCursorToTheStartOfDocumentWithSelection { get; set; } + public List MoveCursorToTheEndOfDocumentWithSelection { get; set; } + + + } +} diff --git a/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs b/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs index e2e8a34676..9604e9975b 100644 --- a/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs +++ b/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs @@ -81,6 +81,7 @@ namespace Avalonia.Gtk3 .Bind().ToSingleton() .Bind().ToConstant(new RenderLoop()) .Bind().ToConstant(new DefaultRenderTimer(60)) + .Bind().ToSingleton() .Bind().ToConstant(new PlatformIconLoader()); if (useGpu) EglGlPlatformFeature.TryInitialize(); diff --git a/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs b/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs index 9046c26cee..9ed06c978d 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs @@ -5,6 +5,7 @@ using Avalonia.Controls; using Avalonia.Controls.Embedding; using Avalonia.Controls.Platform; using Avalonia.Input; +using Avalonia.Input.Platform; using Avalonia.LinuxFramebuffer; using Avalonia.Platform; using Avalonia.Rendering; @@ -36,6 +37,7 @@ namespace Avalonia.LinuxFramebuffer .Bind().ToSingleton() .Bind().ToConstant(Threading) .Bind().ToConstant(new RenderLoop()) + .Bind().ToSingleton() .Bind().ToConstant(Threading); } diff --git a/src/OSX/Avalonia.MonoMac/MonoMacPlatform.cs b/src/OSX/Avalonia.MonoMac/MonoMacPlatform.cs index 5757413b7a..0d2d4d3f9c 100644 --- a/src/OSX/Avalonia.MonoMac/MonoMacPlatform.cs +++ b/src/OSX/Avalonia.MonoMac/MonoMacPlatform.cs @@ -37,6 +37,7 @@ namespace Avalonia.MonoMac .Bind().ToSingleton() .Bind().ToConstant(s_renderLoop) .Bind().ToConstant(s_renderTimer) + .Bind().ToConstant(new PlatformHotkeyConfiguration(InputModifiers.Windows)) .Bind().ToConstant(PlatformThreadingInterface.Instance) /*.Bind().ToTransient()*/; } diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index 5041942c63..33bee4a82a 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -89,6 +89,7 @@ namespace Avalonia.Win32 .Bind().ToConstant(new RenderTimer(60)) .Bind().ToSingleton() .Bind().ToConstant(s_instance) + .Bind().ToSingleton() .Bind().ToConstant(s_instance); Win32GlManager.Initialize(); UseDeferredRendering = deferredRendering; diff --git a/src/iOS/Avalonia.iOS/iOSPlatform.cs b/src/iOS/Avalonia.iOS/iOSPlatform.cs index 7b50040bf2..b0092bc98a 100644 --- a/src/iOS/Avalonia.iOS/iOSPlatform.cs +++ b/src/iOS/Avalonia.iOS/iOSPlatform.cs @@ -42,6 +42,7 @@ namespace Avalonia.iOS .Bind().ToSingleton() .Bind().ToSingleton() .Bind().ToSingleton() + .Bind().ToSingleton() .Bind().ToSingleton(); } } diff --git a/tests/Avalonia.UnitTests/UnitTestApplication.cs b/tests/Avalonia.UnitTests/UnitTestApplication.cs index 359198048b..5c53334f44 100644 --- a/tests/Avalonia.UnitTests/UnitTestApplication.cs +++ b/tests/Avalonia.UnitTests/UnitTestApplication.cs @@ -11,6 +11,7 @@ using Avalonia.Rendering; using Avalonia.Threading; using System.Reactive.Disposables; using System.Reactive.Concurrency; +using Avalonia.Input.Platform; namespace Avalonia.UnitTests { @@ -58,6 +59,7 @@ namespace Avalonia.UnitTests .Bind().ToConstant(Services.StandardCursorFactory) .Bind().ToConstant(Services.Styler) .Bind().ToConstant(Services.WindowingPlatform) + .Bind().ToSingleton() .Bind().ToConstant(this); var styles = Services.Theme?.Invoke(); From 4d2407192ce33e9efee92a4861578fbc5786949a Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 13 Oct 2018 19:40:05 +0300 Subject: [PATCH 2/3] Added WholeWordTextActionModifiers --- src/Avalonia.Controls/TextBox.cs | 33 ++++++++++--------- .../Platform/PlatformHotkeyConfiguration.cs | 6 +++- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index 56c5129275..d6c3a1041e 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -495,34 +495,36 @@ namespace Avalonia.Controls handled = true; } else + { + bool hasWholeWordModifiers = modifiers.HasFlag(keymap.WholeWordTextActionModifiers); switch (e.Key) { case Key.Left: - MoveHorizontal(-1, modifiers); + MoveHorizontal(-1, hasWholeWordModifiers); movement = true; selection = DetectSelection(); break; case Key.Right: - MoveHorizontal(1, modifiers); + MoveHorizontal(1, hasWholeWordModifiers); movement = true; selection = DetectSelection(); break; case Key.Up: - movement = MoveVertical(-1, modifiers); + movement = MoveVertical(-1); selection = DetectSelection(); break; case Key.Down: - movement = MoveVertical(1, modifiers); + movement = MoveVertical(1); selection = DetectSelection(); break; case Key.Back: - if (modifiers == keymap.CommandModifiers && SelectionStart == SelectionEnd) + if (hasWholeWordModifiers && SelectionStart == SelectionEnd) { - SetSelectionForControlBackspace(modifiers); + SetSelectionForControlBackspace(); } if (!DeleteSelection() && CaretIndex > 0) @@ -548,9 +550,9 @@ namespace Avalonia.Controls break; case Key.Delete: - if (modifiers == keymap.CommandModifiers && SelectionStart == SelectionEnd) + if (hasWholeWordModifiers && SelectionStart == SelectionEnd) { - SetSelectionForControlDelete(modifiers); + SetSelectionForControlDelete(); } if (!DeleteSelection() && caretIndex < text.Length) @@ -599,6 +601,7 @@ namespace Avalonia.Controls handled = false; break; } + } if (movement && selection) { @@ -719,12 +722,12 @@ namespace Avalonia.Controls return result; } - private void MoveHorizontal(int direction, InputModifiers modifiers) + private void MoveHorizontal(int direction, bool wholeWord) { var text = Text ?? string.Empty; var caretIndex = CaretIndex; - if ((modifiers & InputModifiers.Control) == 0) + if (!wholeWord) { var index = caretIndex + direction; @@ -762,7 +765,7 @@ namespace Avalonia.Controls } } - private bool MoveVertical(int count, InputModifiers modifiers) + private bool MoveVertical(int count) { var formattedText = _presenter.FormattedText; var lines = formattedText.GetLines().ToList(); @@ -935,17 +938,17 @@ namespace Avalonia.Controls } } - private void SetSelectionForControlBackspace(InputModifiers modifiers) + private void SetSelectionForControlBackspace() { SelectionStart = CaretIndex; - MoveHorizontal(-1, modifiers); + MoveHorizontal(-1, true); SelectionEnd = CaretIndex; } - private void SetSelectionForControlDelete(InputModifiers modifiers) + private void SetSelectionForControlDelete() { SelectionStart = CaretIndex; - MoveHorizontal(1, modifiers); + MoveHorizontal(1, true); SelectionEnd = CaretIndex; } diff --git a/src/Avalonia.Input/Platform/PlatformHotkeyConfiguration.cs b/src/Avalonia.Input/Platform/PlatformHotkeyConfiguration.cs index 5f3093df78..a758a328be 100644 --- a/src/Avalonia.Input/Platform/PlatformHotkeyConfiguration.cs +++ b/src/Avalonia.Input/Platform/PlatformHotkeyConfiguration.cs @@ -9,10 +9,13 @@ namespace Avalonia.Input.Platform } - public PlatformHotkeyConfiguration(InputModifiers commandModifiers, InputModifiers selectionModifiers = InputModifiers.Shift) + public PlatformHotkeyConfiguration(InputModifiers commandModifiers, + InputModifiers selectionModifiers = InputModifiers.Shift, + InputModifiers wholeWordTextActionModifiers = InputModifiers.Control) { CommandModifiers = commandModifiers; SelectionModifiers = selectionModifiers; + WholeWordTextActionModifiers = wholeWordTextActionModifiers; Copy = new List { new KeyGesture(Key.C, commandModifiers) @@ -73,6 +76,7 @@ namespace Avalonia.Input.Platform } public InputModifiers CommandModifiers { get; set; } + public InputModifiers WholeWordTextActionModifiers { get; set; } public InputModifiers SelectionModifiers { get; set; } public List Copy { get; set; } public List Cut { get; set; } From 94b379096af08d9f7c6b9758600ad734009f1cde Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 13 Oct 2018 19:40:34 +0300 Subject: [PATCH 3/3] Fixed ALT on GTK --- src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs b/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs index 0ec4047086..6e8cf5cb18 100644 --- a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs +++ b/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs @@ -126,7 +126,7 @@ namespace Avalonia.Gtk3 if (state.HasFlag(GdkModifierType.ShiftMask)) rv |= InputModifiers.Shift; if (state.HasFlag(GdkModifierType.Mod1Mask)) - rv |= InputModifiers.Control; + rv |= InputModifiers.Alt; if (state.HasFlag(GdkModifierType.Button1Mask)) rv |= InputModifiers.LeftMouseButton; if (state.HasFlag(GdkModifierType.Button2Mask))