Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#459 IME UI does not follow the cursor in Windows Terminal #1919

Merged
merged 33 commits into from
Nov 22, 2019
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b57310d
Add TSF3.0 IME UserControl
Jun 20, 2019
17b624d
Trying to figure out why Surface Pro 6 isn't working right
Jul 8, 2019
1a69d5c
Add documentation, getting ready for review
Jul 9, 2019
77c6197
Minor code formatting updates
Jul 9, 2019
466fd96
More changes to get ready for draft PR
Jul 9, 2019
078c69f
Add Exception handling around std::wstring operations
Jul 9, 2019
3a097ca
Add TSF3.0 IME UserControl
Jun 20, 2019
578578c
Trying to figure out why Surface Pro 6 isn't working right
Jul 8, 2019
882e97f
Add documentation, getting ready for review
Jul 9, 2019
28e99d0
Minor code formatting updates
Jul 9, 2019
b890187
More changes to get ready for draft PR
Jul 9, 2019
4cec73a
Add Exception handling around std::wstring operations
Jul 9, 2019
8309559
Merge branch 'dev/philnach/459-TSF30-IME_2' of https://github.com/phi…
Jul 10, 2019
f309dfe
Removing Outputdebugstrings
Jul 10, 2019
2afe5f3
Apply Formatting fixes that caused code formatting failures
Jul 11, 2019
ebf3d8c
The FontWidth and Height properties weren't used on the TSFInputControl
Jul 11, 2019
41a373b
applying const to where appropriate
philnach Jul 25, 2019
c3c42e9
Merging with upstream
Oct 23, 2019
35c456a
Fix incorrect merge
Oct 23, 2019
f9e3ab9
More const changes
Nov 19, 2019
714d00a
Merge branch 'master' into dev/philnach/459-TSF30-IME_2
Nov 19, 2019
39aea27
Code Analysis Errors
Nov 19, 2019
cec486a
Remove TAB OFFSET Hack
Nov 20, 2019
e781a85
Add GitHub issues for all TODOs in TSFInputControl
Nov 20, 2019
a1b5c3a
Add more TODO github linked issues
Nov 20, 2019
8354fc1
Fix Code Formatting errors
Nov 20, 2019
30bfc3e
Update src/cascadia/TerminalControl/TSFInputControl.cpp
philnach Nov 21, 2019
04d1a63
Move Color conversion to WinRT Utils library
Nov 21, 2019
facb878
Add missing file header
Nov 21, 2019
d2a0ae8
Address PR feedback, switched to TYPED_EVENT, newer Exception Macro, …
Nov 21, 2019
4bafb32
Switch to GETSET_PROPERTY macro
Nov 21, 2019
9108b41
Adjust fontsize as supposed to fixed size
Nov 21, 2019
12c1ac6
LogicalDPI was not the right call it's always 96
Nov 21, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
380 changes: 380 additions & 0 deletions src/cascadia/TerminalControl/TSFInputControl.cpp

Large diffs are not rendered by default.

101 changes: 101 additions & 0 deletions src/cascadia/TerminalControl/TSFInputControl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#pragma once
#include "TSFInputControl.g.h"
#include "CursorPositionEventArgs.g.h"
#include "FontInfoEventArgs.g.h"
#include "cppwinrt_utils.h"

namespace winrt::Microsoft::Terminal::TerminalControl::implementation
{
struct CursorPositionEventArgs :
public CursorPositionEventArgsT<CursorPositionEventArgs>
{
public:
CursorPositionEventArgs(){};

Windows::Foundation::Point CurrentPosition()
philnach marked this conversation as resolved.
Show resolved Hide resolved
{
return _curPos;
}

void CurrentPosition(Windows::Foundation::Point newPosition)
{
_curPos = newPosition;
}

private:
Windows::Foundation::Point _curPos;
};

struct FontInfoEventArgs :
public FontInfoEventArgsT<FontInfoEventArgs>
{
public:
FontInfoEventArgs(){};

Windows::Foundation::Size FontSize()
{
return _curSize;
}

void FontSize(Windows::Foundation::Size newSize)
{
_curSize = newSize;
}

winrt::hstring FontFace()
{
return _fontFace;
}

void FontFace(winrt::hstring newFontFace)
{
_fontFace = newFontFace;
}

private:
winrt::hstring _fontFace;
Windows::Foundation::Size _curSize;
};

struct TSFInputControl : TSFInputControlT<TSFInputControl>
{
public:
TSFInputControl();

void NotifyFocusEnter();
void NotifyFocusLeave();

static void OnCompositionChanged(Windows::UI::Xaml::DependencyObject const&, Windows::UI::Xaml::DependencyPropertyChangedEventArgs const&);

// -------------------------------- WinRT Events ---------------------------------
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CurrentCursorPosition, _currentCursorPositionHandlers, TerminalControl::TSFInputControl, TerminalControl::CursorPositionEventArgs);
DECLARE_EVENT_WITH_TYPED_EVENT_HANDLER(CurrentFontInfo, _currentFontInfoHandlers, TerminalControl::TSFInputControl, TerminalControl::FontInfoEventArgs);
DECLARE_EVENT(CompositionCompleted, _compositionCompletedHandlers, TerminalControl::CompositionCompletedEventArgs);

private:
void _layoutRequestedHandler(winrt::Windows::UI::Text::Core::CoreTextEditContext sender, winrt::Windows::UI::Text::Core::CoreTextLayoutRequestedEventArgs const& args);
void _compositionStartedHandler(winrt::Windows::UI::Text::Core::CoreTextEditContext sender, winrt::Windows::UI::Text::Core::CoreTextCompositionStartedEventArgs const& args);
void _compositionCompletedHandler(winrt::Windows::UI::Text::Core::CoreTextEditContext sender, winrt::Windows::UI::Text::Core::CoreTextCompositionCompletedEventArgs const& args);
void _focusRemovedHandler(winrt::Windows::UI::Text::Core::CoreTextEditContext sender, winrt::Windows::Foundation::IInspectable const& object);
void _selectionRequestedHandler(winrt::Windows::UI::Text::Core::CoreTextEditContext sender, winrt::Windows::UI::Text::Core::CoreTextSelectionRequestedEventArgs const& args);
void _textRequestedHandler(winrt::Windows::UI::Text::Core::CoreTextEditContext sender, winrt::Windows::UI::Text::Core::CoreTextTextRequestedEventArgs const& args);
void _selectionUpdatingHandler(winrt::Windows::UI::Text::Core::CoreTextEditContext sender, winrt::Windows::UI::Text::Core::CoreTextSelectionUpdatingEventArgs const& args);
void _textUpdatingHandler(winrt::Windows::UI::Text::Core::CoreTextEditContext sender, winrt::Windows::UI::Text::Core::CoreTextTextUpdatingEventArgs const& args);
void _formatUpdatingHandler(winrt::Windows::UI::Text::Core::CoreTextEditContext sender, winrt::Windows::UI::Text::Core::CoreTextFormatUpdatingEventArgs const& args);

Windows::UI::Xaml::Controls::Canvas _canvas;
Windows::UI::Xaml::Controls::TextBlock _textBlock;

Windows::UI::Text::Core::CoreTextEditContext _editContext;

std::wstring _inputBuffer;

void _Create();
};
}
namespace winrt::Microsoft::Terminal::TerminalControl::factory_implementation
{
struct TSFInputControl : TSFInputControlT<TSFInputControl, implementation::TSFInputControl>
{
};
}
31 changes: 31 additions & 0 deletions src/cascadia/TerminalControl/TSFInputControl.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

namespace Microsoft.Terminal.TerminalControl
{
delegate void CompositionCompletedEventArgs(String text);

runtimeclass CursorPositionEventArgs
{
Windows.Foundation.Point CurrentPosition { get; set; };
}

runtimeclass FontInfoEventArgs
{
String FontFace { get; set; };
Windows.Foundation.Size FontSize { get; set; };
}

[default_interface]
runtimeclass TSFInputControl : Windows.UI.Xaml.Controls.UserControl
{
TSFInputControl();

event CompositionCompletedEventArgs CompositionCompleted;
event Windows.Foundation.TypedEventHandler<TSFInputControl, CursorPositionEventArgs> CurrentCursorPosition;
event Windows.Foundation.TypedEventHandler<TSFInputControl, FontInfoEventArgs> CurrentFontInfo;

void NotifyFocusEnter();
void NotifyFocusLeave();
}
}
78 changes: 77 additions & 1 deletion src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,22 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_touchAnchor{ std::nullopt },
_cursorTimer{},
_lastMouseClick{},
_lastMouseClickPos{}
_lastMouseClickPos{},
_tsfInputControl{ nullptr }
{
_EnsureStaticInitialization();
_Create();
}

inline winrt::Windows::UI::Color ColorRefToColor(const COLORREF& colorref)
philnach marked this conversation as resolved.
Show resolved Hide resolved
{
winrt::Windows::UI::Color color;
color.R = GetRValue(colorref);
color.G = GetGValue(colorref);
color.B = GetBValue(colorref);
return color;
}

void TermControl::_Create()
{
Controls::Grid container;
Expand Down Expand Up @@ -101,6 +111,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_scrollBar.LargeChange(4);
_scrollBar.Visibility(Visibility::Visible);

_tsfInputControl = TSFInputControl();
_tsfInputControl.CompositionCompleted({ this, &TermControl::_CompositionCompleted });
_tsfInputControl.CurrentCursorPosition({ this, &TermControl::_CurrentCursorPositionHandler });
_tsfInputControl.CurrentFontInfo({ this, &TermControl::_FontInfoHandler });
container.Children().Append(_tsfInputControl);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we may need to tell the accessibility subsystem something about this, but I am not sure what. @carlos-zamora?


// Create the SwapChainPanel that will display our content
Controls::SwapChainPanel swapChainPanel;

Expand Down Expand Up @@ -193,6 +209,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
auto lock = _terminal->LockForWriting();
_DoResize(width, height);
}

// set TSF Foreground
Media::SolidColorBrush foregroundBrush{};
foregroundBrush.Color(ColorRefToColor(_settings.DefaultForeground()));
_tsfInputControl.Foreground(foregroundBrush);
});
}

Expand Down Expand Up @@ -245,6 +266,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
// The Codepage is additionally not actually used by the DX engine at all.
_actualFont = { fontFace, 0, 10, { 0, fontHeight }, CP_UTF8, false };
_desiredFont = { _actualFont };

// set TSF Foreground
Media::SolidColorBrush foregroundBrush{};
foregroundBrush.Color(ColorRefToColor(_settings.DefaultForeground()));
_tsfInputControl.Foreground(foregroundBrush);
_tsfInputControl.Margin(newMargin);
}

// Method Description:
Expand Down Expand Up @@ -1188,6 +1215,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
}
_focused = true;

if (_tsfInputControl != nullptr)
{
_tsfInputControl.NotifyFocusEnter();
}

if (_cursorTimer.has_value())
{
_cursorTimer.value().Start();
Expand All @@ -1206,6 +1238,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
}
_focused = false;

if (_tsfInputControl != nullptr)
{
_tsfInputControl.NotifyFocusLeave();
}

if (_cursorTimer.has_value())
{
_cursorTimer.value().Stop();
Expand Down Expand Up @@ -1866,6 +1903,45 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
return terminalPosition;
}

// Method Description:
// - Composition Completion handler for the TSFInputControl that
// handles writing text out to TerminalConnection
// Arguments:
// - text: the text to write to TerminalConnection
// Return Value:
// - <none>
void TermControl::_CompositionCompleted(winrt::hstring text)
{
_connection.WriteInput(text);
}

// Method Description:
// - CurrentCursorPosition handler for the TSFInputControl that
// handles returning current cursor position.
// Arguments:
// - eventArgs: event for storing the current cursor position
// Return Value:
// - <none>
void TermControl::_CurrentCursorPositionHandler(const IInspectable& /*sender*/, const CursorPositionEventArgs& eventArgs)
{
const COORD cursorPos = _terminal->GetCursorPosition();
Windows::Foundation::Point p = { gsl::narrow<float>(cursorPos.X), gsl::narrow<float>(cursorPos.Y) };
eventArgs.CurrentPosition(p);
}

// Method Description:
// - FontInfo handler for the TSFInputControl that
// handles returning current font information
// Arguments:
// - eventArgs: event for storing the current font information
// Return Value:
// - <none>
void TermControl::_FontInfoHandler(const IInspectable& /*sender*/, const FontInfoEventArgs& eventArgs)
{
eventArgs.FontSize(CharacterDimensions());
eventArgs.FontFace(_actualFont.GetFaceName());
}

// Method Description:
// - Returns the number of clicks that occurred (double and triple click support)
// Arguments:
Expand Down
9 changes: 8 additions & 1 deletion src/cascadia/TerminalControl/TermControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "../../renderer/base/Renderer.hpp"
#include "../../renderer/dx/DxRenderer.hpp"
#include "../../cascadia/TerminalCore/Terminal.hpp"
#include "../../cascadia/inc/cppwinrt_utils.h"
#include "cppwinrt_utils.h"

namespace winrt::Microsoft::Terminal::TerminalControl::implementation
{
Expand Down Expand Up @@ -101,6 +101,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
Windows::UI::Xaml::Controls::Image _bgImageLayer;
Windows::UI::Xaml::Controls::SwapChainPanel _swapChainPanel;
Windows::UI::Xaml::Controls::Primitives::ScrollBar _scrollBar;
TSFInputControl _tsfInputControl;

event_token _connectionOutputEventToken;

std::unique_ptr<::Microsoft::Terminal::Core::Terminal> _terminal;
Expand Down Expand Up @@ -196,6 +198,11 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
const COORD _GetTerminalPosition(winrt::Windows::Foundation::Point cursorPosition);
const unsigned int _NumberOfClicks(winrt::Windows::Foundation::Point clickPos, Timestamp clickTime);
double _GetAutoScrollSpeed(double cursorDistanceFromBorder) const;

// TSFInputControl Handlers
void _CompositionCompleted(winrt::hstring text);
void _CurrentCursorPositionHandler(const IInspectable& /*sender*/, const CursorPositionEventArgs& eventArgs);
void _FontInfoHandler(const IInspectable& /*sender*/, const FontInfoEventArgs& eventArgs);
};
}

Expand Down
9 changes: 8 additions & 1 deletion src/cascadia/TerminalControl/TerminalControl.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
<ClInclude Include="TermControlAutomationPeer.h">
<DependentUpon>TermControlAutomationPeer.idl</DependentUpon>
</ClInclude>
<ClInclude Include="TSFInputControl.h">
<DependentUpon>TSFInputControl.idl</DependentUpon>
</ClInclude>
<ClInclude Include="UiaTextRange.hpp" />
<ClInclude Include="XamlUiaTextRange.h" />
</ItemGroup>
Expand All @@ -43,6 +46,9 @@
<ClCompile Include="TermControl.cpp">
<DependentUpon>TermControl.idl</DependentUpon>
</ClCompile>
<ClCompile Include="TSFInputControl.cpp">
<DependentUpon>TSFInputControl.idl</DependentUpon>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
<ClCompile Include="TermControlAutomationPeer.cpp">
<DependentUpon>TermControlAutomationPeer.idl</DependentUpon>
Expand All @@ -53,6 +59,7 @@
<ItemGroup>
<Midl Include="TermControl.idl" />
<Midl Include="TermControlAutomationPeer.idl" />
<Midl Include="TSFInputControl.idl" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
Expand Down Expand Up @@ -84,7 +91,7 @@
<AdditionalDependencies>dwrite.lib;dxgi.lib;d2d1.lib;d3d11.lib;shcore.lib;winmm.lib;pathcch.lib;propsys.lib;uiautomationcore.lib;Shlwapi.lib;ntdll.lib;user32.lib;kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<ClCompile>
<AdditionalIncludeDirectories>$(OpenConsoleDir)src\types\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(OpenConsoleDir)src\cascadia\inc;$(OpenConsoleDir)src\types\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
</Project>
10 changes: 7 additions & 3 deletions src/cascadia/TerminalControl/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,19 @@
#include <unknwn.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Graphics.Display.h>
#include <winrt/windows.ui.core.h>
#include <winrt/Windows.ui.input.h>
#include <winrt/Windows.UI.Xaml.h>
#include <winrt/Windows.UI.Xaml.Automation.Peers.h>
#include <winrt/Windows.UI.Text.Core.h>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
#include <winrt/Windows.ui.xaml.media.h>
#include <winrt/Windows.ui.xaml.media.imaging.h>
#include <winrt/Windows.ui.xaml.input.h>
#include <winrt/Windows.UI.Xaml.Data.h>
#include <winrt/Windows.UI.Xaml.Media.h>
#include <winrt/Windows.UI.Xaml.Media.Imaging.h>
#include <winrt/Windows.UI.Xaml.Input.h>
#include <winrt/Windows.UI.Xaml.Interop.h>

#include <windows.ui.xaml.media.dxinterop.h>

Expand Down