Skip to content

Commit 830d1d0

Browse files
committed
视口修复
1 parent b15637a commit 830d1d0

4 files changed

Lines changed: 62 additions & 9 deletions

File tree

Assets/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
* 优化了 MCP 调用流程
66
* 优化了软件退出流程
77
* 提升了读操作的并发量
8+
* 修复了局域网远程控制的 Avalonia 根在收到视口前开始渲染会导致软件无响应的问题

DirectorPrompt/Services/BrowserRemoteTransport.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public sealed class BrowserRemoteTransport : IAvaloniaRemoteTransportConnection,
2828

2929
private WebApplication? application;
3030
private PendingFrame? latestFrame;
31+
private bool isStarted;
3132
private long sentSequenceID = -1;
3233
private WebSocket? socket;
3334

@@ -70,6 +71,18 @@ public async Task StartServerAsync(CancellationToken cancellationToken = default
7071

7172
public void Start()
7273
{
74+
isStarted = true;
75+
StartRemoteSession();
76+
}
77+
78+
private void StartRemoteSession()
79+
{
80+
lock (connectionLock)
81+
{
82+
if (!isStarted || socket is null)
83+
return;
84+
}
85+
7386
OnMessage?.Invoke
7487
(
7588
this,
@@ -164,7 +177,7 @@ private async Task HandleRemoteAsync(HttpContext context)
164177
sentSequenceID = -1;
165178
}
166179

167-
Resize(1280, 800);
180+
StartRemoteSession();
168181
await SendLatestFrameAsync();
169182

170183
try
@@ -301,6 +314,9 @@ private void HandleMessage(string message)
301314

302315
private void Resize(double width, double height, double dpi = 96)
303316
{
317+
if (!double.IsFinite(width) || !double.IsFinite(height) || width <= 0 || height <= 0)
318+
return;
319+
304320
OnMessage?.Invoke
305321
(
306322
this,

DirectorPrompt/Services/LanSharingService.cs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Reflection;
66
using System.Runtime.CompilerServices;
77
using Avalonia.Controls;
8+
using Avalonia.Controls.Embedding;
89
using Avalonia.Input;
910
using Avalonia.Interactivity;
1011
using Avalonia.Remote.Protocol;
@@ -28,10 +29,12 @@ RemoteInteractionRouter remoteInteractionRouter
2829

2930
private BrowserRemoteTransport? transport;
3031
private IDisposable? remoteServer;
32+
private EmbeddableControlRoot? remoteRoot;
3133
private Control? remoteContent;
3234
private MainWindow? remoteWindow;
3335
private RemoteWindowService? remoteWindowService;
3436
private Uri? endpoint;
37+
private bool remoteRenderingStarted;
3538

3639
public Uri? Endpoint
3740
{
@@ -109,7 +112,6 @@ await Dispatcher.UIThread.InvokeAsync
109112
);
110113
}
111114

112-
currentTransport.Start();
113115
transport = currentTransport;
114116
Endpoint = new Uri($"http://{address}:{port}/");
115117

@@ -173,6 +175,8 @@ private void DisposeRemoteVisual()
173175
{
174176
remoteServer?.Dispose();
175177
remoteServer = null;
178+
remoteRoot = null;
179+
remoteRenderingStarted = false;
176180
remoteContent?.RemoveHandler(InputElement.PointerReleasedEvent, OnRemoteInteraction);
177181
remoteContent?.RemoveHandler(InputElement.KeyDownEvent, OnRemoteInteraction);
178182
remoteContent?.DataContext = null;
@@ -215,10 +219,15 @@ internal MainWindow CreateRemoteVisual(BrowserRemoteTransport currentTransport)
215219
) ??
216220
throw new InvalidOperationException("Avalonia 远程控制服务不可用");
217221

222+
remoteRoot = serverType.GetField("_topLevel", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(remoteServer) as EmbeddableControlRoot ??
223+
throw new InvalidOperationException("Avalonia 远程控制根不可用");
224+
remoteRoot.StopRendering();
225+
218226
serverType.GetProperty("Content")!.SetValue(remoteServer, content);
219227
currentWindowService.Attach(remoteOverlay, remotePopupLayer);
220228
remoteInteractionRouter.Attach(currentWindowService);
221229
currentTransport.ViewportChanged += OnRemoteViewportChanged;
230+
currentTransport.Start();
222231
remoteContent = content;
223232
remoteWindowService = currentWindowService;
224233
return remoteWindow;
@@ -237,19 +246,40 @@ private void OnRemoteInteraction(object? sender, RoutedEventArgs e)
237246

238247
private void OnRemoteViewportChanged(double width, double height)
239248
{
249+
if (width <= 0 || height <= 0)
250+
return;
251+
240252
if (Dispatcher.UIThread.CheckAccess())
241253
{
242254
remoteWindow?.SetRemoteViewportWidth(width);
255+
ScheduleRemoteRendering();
243256
return;
244257
}
245258

246259
Dispatcher.UIThread.Post
247260
(
248-
() => remoteWindow?.SetRemoteViewportWidth(width),
261+
() =>
262+
{
263+
remoteWindow?.SetRemoteViewportWidth(width);
264+
ScheduleRemoteRendering();
265+
},
249266
DispatcherPriority.Send
250267
);
251268
}
252269

270+
private void ScheduleRemoteRendering()
271+
{
272+
if (remoteRenderingStarted)
273+
return;
274+
275+
remoteRenderingStarted = true;
276+
Dispatcher.UIThread.Post
277+
(
278+
() => remoteRoot?.StartRendering(),
279+
DispatcherPriority.Render
280+
);
281+
}
282+
253283
private static IPAddress GetLanAddress()
254284
{
255285
var address = NetworkInterface.GetAllNetworkInterfaces()

DirectorPrompt/Services/RemotePopupHost.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ private static void PositionCurrentPopup()
8080
if (popupLayer is null || currentPopup is null)
8181
return;
8282

83+
var layerWidth = popupLayer.Bounds.Width;
84+
var layerHeight = popupLayer.Bounds.Height;
85+
86+
if (layerWidth <= 0 || layerHeight <= 0)
87+
return;
88+
8389
var point = currentPopup.Owner.TranslatePoint
8490
(
8591
new Point(0, currentPopup.Owner.Bounds.Height),
@@ -92,14 +98,14 @@ private static void PositionCurrentPopup()
9298
var left = Math.Max(8, point.Value.X);
9399
var top = Math.Max(8, point.Value.Y);
94100

95-
if (popupLayer.Bounds.Width > 0 && currentPopup.Content.Width > popupLayer.Bounds.Width - 16)
96-
currentPopup.Content.Width = Math.Max(0, popupLayer.Bounds.Width - 16);
101+
if (currentPopup.Content.Width > layerWidth - 16)
102+
currentPopup.Content.Width = Math.Max(1, layerWidth - 16);
97103

98-
currentPopup.DismissLayer.Width = Math.Max(0, popupLayer.Bounds.Width);
99-
currentPopup.DismissLayer.Height = Math.Max(0, popupLayer.Bounds.Height);
104+
currentPopup.DismissLayer.Width = layerWidth;
105+
currentPopup.DismissLayer.Height = layerHeight;
100106

101-
if (left + currentPopup.Content.Width > popupLayer.Bounds.Width - 8)
102-
left = Math.Max(8, popupLayer.Bounds.Width - currentPopup.Content.Width - 8);
107+
if (left + currentPopup.Content.Width > layerWidth - 8)
108+
left = Math.Max(8, layerWidth - currentPopup.Content.Width - 8);
103109

104110
Canvas.SetLeft(currentPopup.Content, left);
105111
Canvas.SetTop(currentPopup.Content, top);

0 commit comments

Comments
 (0)