Skip to content

Commit

Permalink
UWP: Basic key events
Browse files Browse the repository at this point in the history
  • Loading branch information
paulrouget committed Jun 30, 2020
1 parent 71bd7a4 commit 2dcb78d
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 30 deletions.
31 changes: 17 additions & 14 deletions ports/libsimpleservo/capi/src/lib.rs
Expand Up @@ -720,30 +720,33 @@ pub extern "C" fn click(x: f32, y: f32) {

#[no_mangle]
pub extern "C" fn key_down(name: *const c_char) {
catch_any_panic(|| {
debug!("key_down");
let name = unsafe { CStr::from_ptr(name) };
let key = Key::from_str(&name.to_str().expect("Can't read string"));
if let Ok(key) = key {
call(|s| s.key_down(key));
} else {
warn!("Received unknown keys");
}
})
debug!("key_up");
key_event(name, false);
}

#[no_mangle]
pub extern "C" fn key_up(name: *const c_char) {
debug!("key_up");
key_event(name, true);
}

fn key_event(name: *const c_char, up: bool) {
catch_any_panic(|| {
debug!("key_up");
let name = unsafe { CStr::from_ptr(name) };
let key = Key::from_str(&name.to_str().expect("Can't read string"));
let name = match name.to_str() {
Ok(name) => name,
Err(..) => {
warn!("Couldn't not read str");
return;
},
};
let key = Key::from_str(&name);
if let Ok(key) = key {
call(|s| s.key_up(key));
call(|s| if up { s.key_up(key) } else { s.key_down(key) });
} else {
warn!("Received unknown keys");
}
})
});
}

#[no_mangle]
Expand Down
1 change: 1 addition & 0 deletions support/hololens/ServoApp/ServoApp.vcxproj
Expand Up @@ -120,6 +120,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Devtools\Client.h" />
<ClInclude Include="ServoControl\Keys.h" />
<ClInclude Include="strutils.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="App.h">
Expand Down
3 changes: 3 additions & 0 deletions support/hololens/ServoApp/ServoApp.vcxproj.filters
Expand Up @@ -43,6 +43,9 @@
<ClInclude Include="Devtools\Client.h">
<Filter>Devtools</Filter>
</ClInclude>
<ClInclude Include="ServoControl\Keys.h">
<Filter>ServoControl</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="Assets\Wide310x150Logo.scale-200.png">
Expand Down
130 changes: 130 additions & 0 deletions support/hololens/ServoApp/ServoControl/Keys.h
@@ -0,0 +1,130 @@
using namespace winrt::Windows::System;

namespace winrt {
std::optional<const char *> KeyToString(Windows::System::VirtualKey key) {
switch (key) {
case VirtualKey::F1:
return "F1";
case VirtualKey::F2:
return "F2";
case VirtualKey::F3:
return "F3";
case VirtualKey::F4:
return "F4";
case VirtualKey::F5:
return "F5";
case VirtualKey::F6:
return "F6";
case VirtualKey::F7:
return "F7";
case VirtualKey::F8:
return "F8";
case VirtualKey::F9:
return "F9";
case VirtualKey::F10:
return "F10";
case VirtualKey::F11:
return "F11";
case VirtualKey::F12:
return "F12";
case VirtualKey::Shift:
return "Shift";
case VirtualKey::LeftShift:
return "Shift";
case VirtualKey::RightShift:
return "Shift";
case VirtualKey::Control:
return "Control";
case VirtualKey::LeftControl:
return "Control";
case VirtualKey::RightControl:
return "Control";
case VirtualKey::Escape:
return "Escape";
case VirtualKey::Enter:
return "Enter";
case VirtualKey::Tab:
return "Tab";
case VirtualKey::Delete:
return "Delete";
case VirtualKey::Back:
return "Backspace";
case VirtualKey::GoForward:
return "BrowserForward";
case VirtualKey::GoBack:
return "BrowserBack";
case VirtualKey::GoHome:
return "BrowserHome";
case VirtualKey::Favorites:
return "BrowserFavorites";
case VirtualKey::Search:
return "BrowserSearch";
case VirtualKey::Stop:
return "BrowserStop";
case VirtualKey::Menu:
return "Alt";
case VirtualKey::RightMenu:
return "Alt";
case VirtualKey::LeftMenu:
return "Alt";
case VirtualKey::CapitalLock:
return "CapsLock";
case VirtualKey::LeftWindows:
return "Meta";
case VirtualKey::RightWindows:
return "Meta";
case VirtualKey::NumberKeyLock:
return "NumLock";
case VirtualKey::Scroll:
return "ScrollLock";
case VirtualKey::Down:
return "ArrowDown";
case VirtualKey::Up:
return "ArrowUp";
case VirtualKey::Left:
return "ArrowLeft";
case VirtualKey::Right:
return "ArrowRight";
case VirtualKey::End:
return "End";
case VirtualKey::Home:
return "Home";
case VirtualKey::PageDown:
return "PageHome";
case VirtualKey::PageUp:
return "PageUp";
case VirtualKey::Clear:
return "Clear";
case VirtualKey::Insert:
return "Insert";
case VirtualKey::Accept:
return "Accept";
case VirtualKey::Cancel:
return "Cancel";
case VirtualKey::Execute:
return "Execute";
case VirtualKey::Help:
return "Help";
case VirtualKey::Pause:
return "Pause";
case VirtualKey::Select:
return "Select";
case VirtualKey::Print:
return "Print";
case VirtualKey::Convert:
return "Convert";
case VirtualKey::NonConvert:
return "NonConvert";
case VirtualKey::ModeChange:
return "ModeChange";
case VirtualKey::Hangul:
return "HangulMode";
case VirtualKey::Hanja:
return "HanjaMode";
case VirtualKey::Junja:
return "JunjaMode";
default:
return {};
}
}
} // namespace winrt
2 changes: 2 additions & 0 deletions support/hololens/ServoApp/ServoControl/Servo.h
Expand Up @@ -63,6 +63,8 @@ class Servo {
void TouchMove(float x, float y, int32_t id) { touch_move(x, y, id); }
void TouchCancel(float x, float y, int32_t id) { touch_cancel(x, y, id); }
void MouseMove(float x, float y) { mouse_move(x, y); }
void KeyDown(const char *k) { key_down(k); }
void KeyUp(const char *k) { key_up(k); }

void Reload() { reload(); }
void Stop() { stop(); }
Expand Down
86 changes: 70 additions & 16 deletions support/hololens/ServoApp/ServoControl/ServoControl.cpp
Expand Up @@ -4,13 +4,15 @@
#include "ServoControl.g.cpp"
#include "Pref.g.cpp"
#include <stdlib.h>
#include "Keys.h"

using namespace std::placeholders;
using namespace winrt::Windows::ApplicationModel::Resources;
using namespace winrt::Windows::Graphics::Display;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Popups;
using namespace winrt::Windows::UI::Core;
using namespace winrt::Windows::UI::Text::Core;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::System;
using namespace winrt::Windows::Devices::Input;
Expand Down Expand Up @@ -66,21 +68,19 @@ void ServoControl::OnLoaded(IInspectable const &, RoutedEventArgs const &) {
std::bind(&ServoControl::OnSurfacePointerMoved, this, _1, _2));
panel.PointerWheelChanged(
std::bind(&ServoControl::OnSurfaceWheelChanged, this, _1, _2));
panel.ManipulationStarted(
[=](IInspectable const &,
Input::ManipulationStartedRoutedEventArgs const &e) {
mOnCaptureGesturesStartedEvent();
e.Handled(true);
});
panel.ManipulationCompleted(
[=](IInspectable const &,
Input::ManipulationCompletedRoutedEventArgs const &e) {
mOnCaptureGesturesEndedEvent();
e.Handled(true);
});
panel.ManipulationStarted([=](const auto &, const auto &e) {
mOnCaptureGesturesStartedEvent();
e.Handled(true);
});
panel.ManipulationCompleted([=](const auto &, const auto &e) {
mOnCaptureGesturesEndedEvent();
e.Handled(true);
});
panel.ManipulationDelta(
std::bind(&ServoControl::OnSurfaceManipulationDelta, this, _1, _2));
Panel().SizeChanged(std::bind(&ServoControl::OnSurfaceResized, this, _1, _2));
panel.SizeChanged(std::bind(&ServoControl::OnSurfaceResized, this, _1, _2));

InitializeTextController();
InitializeConditionVariable(&mGLCondVar);
InitializeCriticalSection(&mGLLock);
InitializeConditionVariable(&mDialogCondVar);
Expand All @@ -89,6 +89,54 @@ void ServoControl::OnLoaded(IInspectable const &, RoutedEventArgs const &) {
StartRenderLoop();
}

void ServoControl::InitializeTextController() {
mInputPane = Windows::UI::ViewManagement::InputPane::GetForCurrentView();
auto manager = CoreTextServicesManager::GetForCurrentView();
mEditContext = manager.CreateEditContext();
mEditContext->InputPaneDisplayPolicy(CoreTextInputPaneDisplayPolicy::Manual);
mEditContext->InputScope(CoreTextInputScope::Text);
mEditContext->TextRequested([=](const auto &, const auto &e) {
e.Request().Text(L"");
CoreTextRange sel;
sel.StartCaretPosition = 0;
sel.EndCaretPosition = 0;
e.Request().Range() = sel;
});

mEditContext->TextUpdating([=](const auto &, const auto &e) {
RunOnGLThread([=] {
auto keystr = *hstring2char((e.Text()));
mServo->KeyDown(keystr);
});
});

mEditContext->SelectionRequested([](const auto &, const auto &) {});

GotFocus(
[=](const auto &, const auto &) { mEditContext->NotifyFocusEnter(); });
LostFocus(
[=](const auto &, const auto &) { mEditContext->NotifyFocusLeave(); });

PreviewKeyDown([=](const auto &, const auto &e) {
auto keystr = KeyToString(e.Key());
if (keystr.has_value()) {
RunOnGLThread([=] {
auto keyname = *keystr;
mServo->KeyDown(keyname);
});
}
});
PreviewKeyUp([=](const auto &, const auto &e) {
auto keystr = KeyToString(e.Key());
if (keystr.has_value()) {
RunOnGLThread([=] {
auto keyname = *keystr;
mServo->KeyUp(keyname);
});
}
});
}

Controls::SwapChainPanel ServoControl::Panel() {
return GetTemplateChild(L"swapChainPanel").as<Controls::SwapChainPanel>();
}
Expand Down Expand Up @@ -128,6 +176,7 @@ void ServoControl::OnSurfaceManipulationDelta(

void ServoControl::OnSurfaceTapped(IInspectable const &,
Input::TappedRoutedEventArgs const &e) {
Focus(FocusState::Programmatic);
if (e.PointerDeviceType() == PointerDeviceType::Mouse) {
auto coords = e.GetPosition(Panel());
auto x = coords.X * mDPI;
Expand Down Expand Up @@ -439,9 +488,14 @@ void ServoControl::OnServoAnimatingChanged(bool animating) {
WakeConditionVariable(&mGLCondVar);
}

void ServoControl::OnServoIMEStateChanged(bool) {
// FIXME:
// https://docs.microsoft.com/en-us/windows/win32/winauto/uiauto-implementingtextandtextrange
void ServoControl::OnServoIMEStateChanged(bool focused) {
RunOnUIThread([=] {
if (focused) {
mInputPane->TryShow();
} else {
mInputPane->TryHide();
}
});
}

void ServoControl::OnServoMediaSessionMetadata(hstring title, hstring artist,
Expand Down
4 changes: 4 additions & 0 deletions support/hololens/ServoApp/ServoControl/ServoControl.h
Expand Up @@ -265,6 +265,7 @@ struct ServoControl : ServoControlT<ServoControl>, public servo::ServoDelegate {
void RunOnGLThread(std::function<void()>);

void TryLoadUri(hstring);
void InitializeTextController();

std::unique_ptr<servo::Servo> mServo;
PropertySet mNativeWindowProperties;
Expand All @@ -278,6 +279,9 @@ struct ServoControl : ServoControlT<ServoControl>, public servo::ServoDelegate {
hstring mArgs;
std::optional<servo::Servo::MouseButton> mPressedMouseButton = {};
std::unique_ptr<L10NStrings> mL10NStrings = nullptr;

std::optional<Windows::UI::Text::Core::CoreTextEditContext> mEditContext;
std::optional<Windows::UI::ViewManagement::InputPane> mInputPane;
};
} // namespace winrt::ServoApp::implementation

Expand Down
1 change: 1 addition & 0 deletions support/hololens/ServoApp/pch.h
Expand Up @@ -60,6 +60,7 @@
#include <winrt/Windows.UI.Xaml.Shapes.h>
#include <winrt/Windows.UI.Notifications.h>
#include <winrt/Windows.UI.Text.h>
#include <winrt/Windows.UI.Text.Core.h>
#include <winrt/Windows.Data.Xml.Dom.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.Data.Json.h>
Expand Down

0 comments on commit 2dcb78d

Please sign in to comment.