1
- using System ;
1
+ #nullable enable
2
+
3
+ using System ;
2
4
using System . Collections . Generic ;
3
5
using System . Linq ;
4
6
using System . Threading . Tasks ;
9
11
using Avalonia . Native . Interop ;
10
12
using Avalonia . Platform . Storage ;
11
13
using Avalonia . Platform . Storage . FileIO ;
12
- using MicroCom . Runtime ;
13
14
14
15
namespace Avalonia . Native
15
16
{
16
17
class ClipboardImpl : IClipboard , IDisposable
17
18
{
18
- private IAvnClipboard _native ;
19
+ private IAvnClipboard ? _native ;
19
20
20
21
// TODO hide native types behind IAvnClipboard abstraction, so managed side won't depend on macOS.
21
22
private const string NSPasteboardTypeString = "public.utf8-plain-text" ;
@@ -26,33 +27,38 @@ public ClipboardImpl(IAvnClipboard native)
26
27
_native = native ;
27
28
}
28
29
30
+ private IAvnClipboard Native
31
+ => _native ?? throw new ObjectDisposedException ( nameof ( ClipboardImpl ) ) ;
32
+
29
33
public Task ClearAsync ( )
30
34
{
31
- _native . Clear ( ) ;
35
+ Native . Clear ( ) ;
32
36
33
37
return Task . CompletedTask ;
34
38
}
35
39
36
- public Task < string > GetTextAsync ( )
40
+ public Task < string ? > GetTextAsync ( )
37
41
{
38
- using ( var text = _native . GetText ( NSPasteboardTypeString ) )
39
- return Task . FromResult ( text . String ) ;
42
+ using ( var text = Native . GetText ( NSPasteboardTypeString ) )
43
+ return Task . FromResult < string ? > ( text . String ) ;
40
44
}
41
45
42
- public unsafe Task SetTextAsync ( string text )
46
+ public Task SetTextAsync ( string ? text )
43
47
{
44
- _native . Clear ( ) ;
48
+ var native = Native ;
49
+
50
+ native . Clear ( ) ;
45
51
46
52
if ( text != null )
47
- _native . SetText ( NSPasteboardTypeString , text ) ;
53
+ native . SetText ( NSPasteboardTypeString , text ) ;
48
54
49
55
return Task . CompletedTask ;
50
56
}
51
57
52
58
public IEnumerable < string > GetFormats ( )
53
59
{
54
60
var rv = new HashSet < string > ( ) ;
55
- using ( var formats = _native . ObtainFormats ( ) )
61
+ using ( var formats = Native . ObtainFormats ( ) )
56
62
{
57
63
var cnt = formats . Count ;
58
64
for ( uint c = 0 ; c < cnt ; c ++ )
@@ -81,27 +87,31 @@ public void Dispose()
81
87
_native = null ;
82
88
}
83
89
84
- public IEnumerable < string > GetFileNames ( )
90
+ public IEnumerable < string > ? GetFileNames ( )
85
91
{
86
- using ( var strings = _native . GetStrings ( NSFilenamesPboardType ) )
92
+ using ( var strings = Native . GetStrings ( NSFilenamesPboardType ) )
87
93
return strings ? . ToStringArray ( ) ;
88
94
}
89
95
90
- public IEnumerable < IStorageItem > GetFiles ( )
96
+ public IEnumerable < IStorageItem > ? GetFiles ( )
91
97
{
92
98
var storageApi = ( StorageProviderApi ) AvaloniaLocator . Current . GetRequiredService < IStorageProviderFactory > ( ) ;
93
99
94
100
// TODO: use non-deprecated AppKit API to get NSUri instead of file names.
95
- return GetFileNames ( ) ?
101
+ var fileNames = GetFileNames ( ) ;
102
+ if ( fileNames is null )
103
+ return null ;
104
+
105
+ return fileNames
96
106
. Select ( f => StorageProviderHelpers . TryGetUriFromFilePath ( f , false ) is { } uri
97
107
? storageApi . TryGetStorageItem ( uri )
98
108
: null )
99
- . Where ( f => f is not null ) ;
109
+ . Where ( f => f is not null ) ! ;
100
110
}
101
111
102
112
public unsafe Task SetDataObjectAsync ( IDataObject data )
103
113
{
104
- _native . Clear ( ) ;
114
+ Native . Clear ( ) ;
105
115
106
116
// If there is multiple values with the same "to" format, prefer these that were not mapped.
107
117
var formats = data . GetDataFormats ( ) . Select ( f =>
@@ -125,26 +135,26 @@ public unsafe Task SetDataObjectAsync(IDataObject data)
125
135
switch ( o )
126
136
{
127
137
case string s :
128
- _native . SetText ( toFormat , s ) ;
138
+ Native . SetText ( toFormat , s ) ;
129
139
break ;
130
140
case IEnumerable < IStorageItem > storageItems :
131
141
using ( var strings = new AvnStringArray ( storageItems
132
142
. Select ( s => s . TryGetLocalPath ( ) )
133
143
. Where ( p => p is not null ) ) )
134
144
{
135
- _native . SetStrings ( toFormat , strings ) ;
145
+ Native . SetStrings ( toFormat , strings ) ;
136
146
}
137
147
break ;
138
148
case IEnumerable < string > managedStrings :
139
149
using ( var strings = new AvnStringArray ( managedStrings ) )
140
150
{
141
- _native . SetStrings ( toFormat , strings ) ;
151
+ Native . SetStrings ( toFormat , strings ) ;
142
152
}
143
153
break ;
144
154
case byte [ ] bytes :
145
155
{
146
156
fixed ( byte * pbytes = bytes )
147
- _native . SetBytes ( toFormat , pbytes , bytes . Length ) ;
157
+ Native . SetBytes ( toFormat , pbytes , bytes . Length ) ;
148
158
break ;
149
159
}
150
160
default :
@@ -161,23 +171,23 @@ public Task<string[]> GetFormatsAsync()
161
171
return Task . FromResult ( GetFormats ( ) . ToArray ( ) ) ;
162
172
}
163
173
164
- public async Task < object > GetDataAsync ( string format )
174
+ public async Task < object ? > GetDataAsync ( string format )
165
175
{
166
176
if ( format == DataFormats . Text || format == NSPasteboardTypeString )
167
177
return await GetTextAsync ( ) ;
168
178
if ( format == DataFormats . FileNames || format == NSFilenamesPboardType )
169
179
return GetFileNames ( ) ;
170
180
if ( format == DataFormats . Files )
171
181
return GetFiles ( ) ;
172
- using ( var n = _native . GetBytes ( format ) )
182
+ using ( var n = Native . GetBytes ( format ) )
173
183
return n . Bytes ;
174
184
}
175
185
}
176
186
177
187
class ClipboardDataObject : IDataObject , IDisposable
178
188
{
179
- private ClipboardImpl _clipboard ;
180
- private List < string > _formats ;
189
+ private ClipboardImpl ? _clipboard ;
190
+ private List < string > ? _formats ;
181
191
182
192
public ClipboardDataObject ( IAvnClipboard clipboard )
183
193
{
@@ -190,14 +200,17 @@ public void Dispose()
190
200
_clipboard = null ;
191
201
}
192
202
193
- List < string > Formats => _formats ??= _clipboard . GetFormats ( ) . ToList ( ) ;
203
+ private ClipboardImpl Clipboard
204
+ => _clipboard ?? throw new ObjectDisposedException ( nameof ( ClipboardDataObject ) ) ;
205
+
206
+ private List < string > Formats => _formats ??= Clipboard . GetFormats ( ) . ToList ( ) ;
194
207
195
208
public IEnumerable < string > GetDataFormats ( ) => Formats ;
196
209
197
210
public bool Contains ( string dataFormat ) => Formats . Contains ( dataFormat ) ;
198
211
199
- public object Get ( string dataFormat ) => _clipboard . GetDataAsync ( dataFormat ) . GetAwaiter ( ) . GetResult ( ) ;
212
+ public object ? Get ( string dataFormat ) => Clipboard . GetDataAsync ( dataFormat ) . GetAwaiter ( ) . GetResult ( ) ;
200
213
201
- public Task SetFromDataObjectAsync ( IDataObject dataObject ) => _clipboard . SetDataObjectAsync ( dataObject ) ;
214
+ public Task SetFromDataObjectAsync ( IDataObject dataObject ) => Clipboard . SetDataObjectAsync ( dataObject ) ;
202
215
}
203
216
}
0 commit comments