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

Add native Windows IME support #4941

Merged
merged 21 commits into from
Jan 11, 2022
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
eb44a5c
Add code path for handling window messages
Susko3 Dec 17, 2021
06d5682
Add Windows-native IME support
Susko3 Dec 17, 2021
ebd1927
Fix license header
Susko3 Dec 18, 2021
ee996dc
Fix formatting
Susko3 Dec 18, 2021
d33430b
Refactor to use SafeHandle
Susko3 Dec 19, 2021
c246b54
Mark `CompositionString` enum as `[Flags]` so `lParam` can be better …
Susko3 Dec 19, 2021
9b15289
Move `SDL_SysWMmsg` struct to separate file
Susko3 Dec 19, 2021
951950a
Fix typo
Susko3 Dec 19, 2021
3904c6a
Also block SDL IME results when there is an ongoing composition
Susko3 Dec 19, 2021
255eb9c
Always block SDL events based on recent IME result instead of matchin…
Susko3 Dec 19, 2021
9acca41
Simplify Windows' `HandleTextInputEvent` since we don't have to check…
Susko3 Dec 19, 2021
f103959
Add `OnSDLEvent`, invoked on every SDL event before it's posted to th…
Susko3 Dec 19, 2021
d3652ae
Migrate Windows IME handling to the new `OnSDLEvent`
Susko3 Dec 19, 2021
0662152
Update `imeCompositionActive` inline with how windows sends IME messages
Susko3 Dec 21, 2021
66e36eb
Throw if `InputContextHandle` is disposed
Susko3 Dec 21, 2021
3f30afd
Remove unnecessary `imeCompositionActive` assignments
Susko3 Dec 21, 2021
305ac93
Move SDL event handling into private helper
Susko3 Jan 4, 2022
102087b
Add IME handling region
Susko3 Jan 4, 2022
a5c3967
Merge branch 'master' into windows-ime
peppy Jan 5, 2022
fd2a77c
Merge branch 'master' into windows-ime
peppy Jan 11, 2022
7873330
Merge branch 'master' into windows-ime
peppy Jan 11, 2022
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
32 changes: 0 additions & 32 deletions osu.Framework/Platform/SDL2/SDL2Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1011,37 +1011,5 @@ public static unsafe bool TryGetStringFromBytePointer(byte* bytePointer, out str
str = Marshal.PtrToStringUTF8(ptr) ?? string.Empty;
return true;
}

// ReSharper disable InconsistentNaming (mimics SDL and SDL2-CS naming)
// ReSharper disable IdentifierTypo

[StructLayout(LayoutKind.Sequential)]
internal struct INTERNAL_windows_wmmsg
{
public IntPtr hwnd;
public uint msg;
public ulong wParam;
public long lParam;
}

[StructLayout(LayoutKind.Explicit)]
internal struct INTERNAL_SysWMmsgUnion
{
[FieldOffset(0)]
public INTERNAL_windows_wmmsg win;

// could add more native events here if required
}

[StructLayout(LayoutKind.Sequential)]
internal struct SDL_SysWMmsg
{
public SDL.SDL_version version;
public SDL.SDL_SYSWM_TYPE subsystem;
public INTERNAL_SysWMmsgUnion msg;
}

// ReSharper restore InconsistentNaming
// ReSharper restore IdentifierTypo
}
}
48 changes: 48 additions & 0 deletions osu.Framework/Platform/SDL2/SDL2Structs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Runtime.InteropServices;
using SDL2;

// ReSharper disable MemberCanBePrivate.Global
// (Some members not currently used)

// ReSharper disable InconsistentNaming
// ReSharper disable IdentifierTypo
// (Mimics SDL and SDL2-CS naming)

namespace osu.Framework.Platform.SDL2
{
internal static class SDL2Structs
{
[StructLayout(LayoutKind.Sequential)]
internal struct INTERNAL_windows_wmmsg
{
public IntPtr hwnd;
public uint msg;
public ulong wParam;
public long lParam;
}

[StructLayout(LayoutKind.Explicit)]
internal struct INTERNAL_SysWMmsgUnion
{
[FieldOffset(0)]
public INTERNAL_windows_wmmsg win;

// could add more native events here if required
}

/// <summary>
/// Member <c>msg</c> of <see cref="SDL.SDL_SysWMEvent"/>.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct SDL_SysWMmsg
{
public SDL.SDL_version version;
public SDL.SDL_SYSWM_TYPE subsystem;
public INTERNAL_SysWMmsgUnion msg;
}
}
}
37 changes: 14 additions & 23 deletions osu.Framework/Platform/SDL2DesktopWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -427,19 +427,22 @@ public virtual void Create()
/// </summary>
public void Run()
{
// polling via SDL_PollEvent blocks on resizes (https://stackoverflow.com/a/50858339)
SDL.SDL_SetEventFilter(eventFilterDelegate = (_, eventPtr) =>
{
// ReSharper disable once PossibleNullReferenceException
var e = (SDL.SDL_Event)Marshal.PtrToStructure(eventPtr, typeof(SDL.SDL_Event));
var e = Marshal.PtrToStructure<SDL.SDL_Event>(eventPtr);
OnSDLEvent?.Invoke(e);

return 1;
}, IntPtr.Zero);

// polling via SDL_PollEvent blocks on resizes (https://stackoverflow.com/a/50858339)
OnSDLEvent += e =>
{
if (e.type == SDL.SDL_EventType.SDL_WINDOWEVENT && e.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED)
{
updateWindowSize();
}

return 1;
}, IntPtr.Zero);
};

while (Exists)
{
Expand Down Expand Up @@ -718,10 +721,6 @@ private void handleSDLEvent(SDL.SDL_Event e)
case SDL.SDL_EventType.SDL_DROPCOMPLETE:
handleDropEvent(e.drop);
break;

case SDL.SDL_EventType.SDL_SYSWMEVENT:
HandleSysWMEvent(e.syswm);
break;
}
}

Expand Down Expand Up @@ -990,19 +989,6 @@ private void handleWindowEvent(SDL.SDL_WindowEvent evtWindow)
}
}

/// <summary>
/// Override if platform requires special handling of native events.
/// </summary>
/// <remarks>
/// Make sure to enable the events with
/// <code>
/// SDL.SDL_EventState(SDL.SDL_EventType.SDL_SYSWMEVENT, SDL.SDL_ENABLE);
/// </code>
/// </remarks>
protected virtual void HandleSysWMEvent(SDL.SDL_SysWMEvent sysWM)
{
}

/// <summary>
/// Should be run on a regular basis to check for external window state changes.
/// </summary>
Expand Down Expand Up @@ -1495,6 +1481,11 @@ private static DisplayMode displayModeFromSDL(SDL.SDL_DisplayMode mode, int disp
/// </summary>
public event Action<string> DragDrop;

/// <summary>
/// Invoked on every SDL event before it's posted to the event queue.
/// </summary>
protected event Action<SDL.SDL_Event> OnSDLEvent;

#endregion

public void Dispose()
Expand Down
Loading