Browse Source

Merge pull request #2082 from AvaloniaUI/osx-fix-clipboard-text-encoding

Fix OSX backend TextEncoding issues
pull/2090/head
Nikita Tsukanov 8 years ago
committed by GitHub
parent
commit
2e05a7fc4f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      native/Avalonia.Native/inc/avalonia-native.h
  2. 6
      native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj
  3. 14
      native/Avalonia.Native/src/OSX/AvnString.h
  4. 55
      native/Avalonia.Native/src/OSX/AvnString.mm
  5. 19
      native/Avalonia.Native/src/OSX/clipboard.mm
  6. 4
      native/Avalonia.Native/src/OSX/window.mm
  7. 16
      src/Avalonia.Native/ClipboardImpl.cs
  8. 6
      src/Avalonia.Native/WindowImpl.cs

12
native/Avalonia.Native/inc/avalonia-native.h

@ -173,6 +173,12 @@ public:
virtual HRESULT ObtainGlFeature(IAvnGlFeature** ppv) = 0;
};
AVNCOM(IAvnString, 17) : IUnknown
{
virtual HRESULT Pointer(void**retOut) = 0;
virtual HRESULT Length(int*ret) = 0;
};
AVNCOM(IAvnWindowBase, 02) : IUnknown
{
virtual HRESULT Show() = 0;
@ -210,7 +216,7 @@ AVNCOM(IAvnWindow, 04) : virtual IAvnWindowBase
virtual HRESULT ShowDialog (IUnknown**ppv) = 0;
virtual HRESULT SetCanResize(bool value) = 0;
virtual HRESULT SetHasDecorations(bool value) = 0;
virtual HRESULT SetTitle (const char* title) = 0;
virtual HRESULT SetTitle (void* utf8Title) = 0;
virtual HRESULT SetTitleBarColor (AvnColor color) = 0;
virtual HRESULT SetWindowState(AvnWindowState state) = 0;
virtual HRESULT GetWindowState(AvnWindowState*ret) = 0;
@ -315,8 +321,8 @@ AVNCOM(IAvnScreens, 0e) : IUnknown
AVNCOM(IAvnClipboard, 0f) : IUnknown
{
virtual HRESULT GetText (void** retOut) = 0;
virtual HRESULT SetText (char* text) = 0;
virtual HRESULT GetText (IAvnString**ppv) = 0;
virtual HRESULT SetText (void* utf8Text) = 0;
virtual HRESULT Clear() = 0;
};

6
native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj

@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
37A517B32159597E00FBA241 /* Screens.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37A517B22159597E00FBA241 /* Screens.mm */; };
37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C09D8721580FE4006A6758 /* SystemDialogs.mm */; };
37DDA9B0219330F8002E132B /* AvnString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37DDA9AF219330F8002E132B /* AvnString.mm */; };
37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37E2330E21583241000CB7E2 /* KeyTransform.mm */; };
5B21A982216530F500CEE36E /* cursor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B21A981216530F500CEE36E /* cursor.mm */; };
5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */; };
@ -26,6 +27,8 @@
37A517B22159597E00FBA241 /* Screens.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Screens.mm; sourceTree = "<group>"; };
37C09D8721580FE4006A6758 /* SystemDialogs.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SystemDialogs.mm; sourceTree = "<group>"; };
37C09D8A21581EF2006A6758 /* window.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = window.h; sourceTree = "<group>"; };
37DDA9AF219330F8002E132B /* AvnString.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AvnString.mm; sourceTree = "<group>"; };
37DDA9B121933371002E132B /* AvnString.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AvnString.h; sourceTree = "<group>"; };
37E2330E21583241000CB7E2 /* KeyTransform.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyTransform.mm; sourceTree = "<group>"; };
5B21A981216530F500CEE36E /* cursor.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = cursor.mm; sourceTree = "<group>"; };
5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = clipboard.mm; sourceTree = "<group>"; };
@ -65,6 +68,8 @@
AB7A61E62147C814003C5833 = {
isa = PBXGroup;
children = (
37DDA9B121933371002E132B /* AvnString.h */,
37DDA9AF219330F8002E132B /* AvnString.mm */,
37A4E71A2178846A00EACBCD /* headers */,
AB573DC3217605E400D389A2 /* gl.mm */,
5BF943652167AD1D009CAE35 /* cursor.h */,
@ -161,6 +166,7 @@
files = (
5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */,
5B21A982216530F500CEE36E /* cursor.mm in Sources */,
37DDA9B0219330F8002E132B /* AvnString.mm in Sources */,
AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */,
37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */,
37A517B32159597E00FBA241 /* Screens.mm in Sources */,

14
native/Avalonia.Native/src/OSX/AvnString.h

@ -0,0 +1,14 @@
//
// AvnString.h
// Avalonia.Native.OSX
//
// Created by Dan Walmsley on 07/11/2018.
// Copyright © 2018 Avalonia. All rights reserved.
//
#ifndef AvnString_h
#define AvnString_h
extern IAvnString* CreateAvnString(NSString* string);
#endif /* AvnString_h */

55
native/Avalonia.Native/src/OSX/AvnString.mm

@ -0,0 +1,55 @@
//
// AvnString.m
// Avalonia.Native.OSX
//
// Created by Dan Walmsley on 07/11/2018.
// Copyright © 2018 Avalonia. All rights reserved.
//
#include "common.h"
class AvnStringImpl : public virtual ComSingleObject<IAvnString, &IID_IAvnString>
{
private:
NSString* _string;
public:
FORWARD_IUNKNOWN()
AvnStringImpl(NSString* string)
{
_string = string;
}
virtual HRESULT Pointer(void**retOut) override
{
@autoreleasepool
{
if(retOut == nullptr)
{
return E_POINTER;
}
*retOut = (void*)_string.UTF8String;
return S_OK;
}
}
virtual HRESULT Length(int*retOut) override
{
if(retOut == nullptr)
{
return E_POINTER;
}
*retOut = (int)_string.length;
return S_OK;
}
};
IAvnString* CreateAvnString(NSString* string)
{
return new AvnStringImpl(string);
}

19
native/Avalonia.Native/src/OSX/clipboard.mm

@ -2,29 +2,34 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
#include "common.h"
#include "AvnString.h"
class Clipboard : public ComSingleObject<IAvnClipboard, &IID_IAvnClipboard>
{
public:
FORWARD_IUNKNOWN()
virtual HRESULT GetText (void** retOut) override
virtual HRESULT GetText (IAvnString**ppv) override
{
@autoreleasepool
{
NSString *str = [[NSPasteboard generalPasteboard] stringForType:NSPasteboardTypeString];
*retOut = (void *)str.UTF8String;
if(ppv == nullptr)
{
return E_POINTER;
}
*ppv = CreateAvnString([[NSPasteboard generalPasteboard] stringForType:NSPasteboardTypeString]);
return S_OK;
}
return S_OK;
}
virtual HRESULT SetText (char* text) override
virtual HRESULT SetText (void* utf8String) override
{
@autoreleasepool
{
NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
[pasteBoard clearContents];
[pasteBoard setString:@(text) forType:NSPasteboardTypeString];
[pasteBoard setString:[NSString stringWithUTF8String:(const char*)utf8String] forType:NSPasteboardTypeString];
}
return S_OK;

4
native/Avalonia.Native/src/OSX/window.mm

@ -530,11 +530,11 @@ private:
}
}
virtual HRESULT SetTitle (const char* title) override
virtual HRESULT SetTitle (void* utf8title) override
{
@autoreleasepool
{
_lastTitle = [NSString stringWithUTF8String:title];
_lastTitle = [NSString stringWithUTF8String:(const char*)utf8title];
[Window setTitle:_lastTitle];
[Window setTitleVisibility:NSWindowTitleVisible];

16
src/Avalonia.Native/ClipboardImpl.cs

@ -5,6 +5,7 @@ using System.Threading.Tasks;
using System.Runtime.InteropServices;
using Avalonia.Input.Platform;
using Avalonia.Native.Interop;
using Avalonia.Platform.Interop;
namespace Avalonia.Native
{
@ -24,12 +25,14 @@ namespace Avalonia.Native
return Task.CompletedTask;
}
public Task<string> GetTextAsync()
public unsafe Task<string> GetTextAsync()
{
var outPtr = _native.GetText();
var text = Marshal.PtrToStringAnsi(outPtr);
using (var text = _native.GetText())
{
var result = System.Text.Encoding.UTF8.GetString((byte*)text.Pointer(), text.Length());
return Task.FromResult(text);
return Task.FromResult(result);
}
}
public Task SetTextAsync(string text)
@ -38,7 +41,10 @@ namespace Avalonia.Native
if (text != null)
{
_native.SetText(text);
using (var buffer = new Utf8Buffer(text))
{
_native.SetText(buffer.DangerousGetHandle());
}
}
return Task.CompletedTask;

6
src/Avalonia.Native/WindowImpl.cs

@ -5,6 +5,7 @@ using System;
using Avalonia.Controls;
using Avalonia.Native.Interop;
using Avalonia.Platform;
using Avalonia.Platform.Interop;
namespace Avalonia.Native
{
@ -68,7 +69,10 @@ namespace Avalonia.Native
public void SetTitle(string title)
{
_native.SetTitle(title);
using (var buffer = new Utf8Buffer(title))
{
_native.SetTitle(buffer.DangerousGetHandle());
}
}
public WindowState WindowState

Loading…
Cancel
Save