diff --git a/Easing.cs b/Easing.cs index 5bb4462..9885a17 100644 --- a/Easing.cs +++ b/Easing.cs @@ -22,8 +22,7 @@ public class Easing public static readonly Easing CubicInOut = new(v => v < 0.5 ? 4.0 * v * v * v : 1.0 - Math.Pow(-2.0 * v + 2.0, 3.0) / 2.0); - public static readonly Easing BounceIn = new(v => 1.0 - BounceOut.Ease(1.0 - v)); - + // BounceOut must be declared before BounceIn since BounceIn references it public static readonly Easing BounceOut = new(v => { const double n1 = 7.5625; @@ -38,6 +37,8 @@ public class Easing return n1 * (v -= 2.625 / d1) * v + 0.984375; }); + public static readonly Easing BounceIn = new(v => 1.0 - BounceOut.Ease(1.0 - v)); + public static readonly Easing SpringIn = new(v => v * v * (2.70158 * v - 1.70158)); public static readonly Easing SpringOut = new(v => diff --git a/Handlers/GestureManager.cs b/Handlers/GestureManager.cs index 21dda87..c2a47a9 100644 --- a/Handlers/GestureManager.cs +++ b/Handlers/GestureManager.cs @@ -188,7 +188,7 @@ public static class GestureManager if (command != null && command.CanExecute(tapRecognizer.CommandParameter)) { Console.WriteLine("[GestureManager] Executing Command"); - tapRecognizer.Command.Execute(tapRecognizer.CommandParameter); + command.Execute(tapRecognizer.CommandParameter); } result = true; } diff --git a/Hosting/LinuxProgramHost.cs b/Hosting/LinuxProgramHost.cs index 8e040d0..26b32db 100644 --- a/Hosting/LinuxProgramHost.cs +++ b/Hosting/LinuxProgramHost.cs @@ -46,7 +46,7 @@ public static class LinuxProgramHost ParseCommandLineOptions(args, options); // Initialize GTK for WebView support - GtkHostService.Instance.Initialize(options.Title, options.Width, options.Height); + GtkHostService.Instance.Initialize(options.Title ?? "MAUI Application", options.Width, options.Height); Console.WriteLine("[LinuxProgramHost] GTK initialized for WebView support"); // Create Linux application diff --git a/Native/GLibNative.cs b/Native/GLibNative.cs index 491c2df..9305ed2 100644 --- a/Native/GLibNative.cs +++ b/Native/GLibNative.cs @@ -28,7 +28,7 @@ public static class GLibNative public static uint IdleAdd(Func callback) { - GSourceFunc wrapper = null; + GSourceFunc wrapper = null!; wrapper = delegate { bool flag = false; @@ -58,7 +58,7 @@ public static class GLibNative public static uint TimeoutAdd(uint intervalMs, Func callback) { - GSourceFunc wrapper = null; + GSourceFunc wrapper = null!; wrapper = delegate { bool flag = false; diff --git a/Services/AppInfoService.cs b/Services/AppInfoService.cs index 225d628..1165793 100644 --- a/Services/AppInfoService.cs +++ b/Services/AppInfoService.cs @@ -41,7 +41,7 @@ public class AppInfoService : IAppInfo { try { - string environmentVariable = Environment.GetEnvironmentVariable("GTK_THEME"); + var environmentVariable = Environment.GetEnvironmentVariable("GTK_THEME"); if (!string.IsNullOrEmpty(environmentVariable) && environmentVariable.Contains("dark", StringComparison.OrdinalIgnoreCase)) { return AppTheme.Dark; diff --git a/Services/DeviceDisplayService.cs b/Services/DeviceDisplayService.cs index e8572b9..ce15034 100644 --- a/Services/DeviceDisplayService.cs +++ b/Services/DeviceDisplayService.cs @@ -73,13 +73,13 @@ public class DeviceDisplayService : IDeviceDisplay private double GetScaleFactor() { - string gdkScale = Environment.GetEnvironmentVariable("GDK_SCALE"); + var gdkScale = Environment.GetEnvironmentVariable("GDK_SCALE"); if (!string.IsNullOrEmpty(gdkScale) && double.TryParse(gdkScale, out var result)) { return result; } - string qtScale = Environment.GetEnvironmentVariable("QT_SCALE_FACTOR"); + var qtScale = Environment.GetEnvironmentVariable("QT_SCALE_FACTOR"); if (!string.IsNullOrEmpty(qtScale) && double.TryParse(qtScale, out result)) { return result; diff --git a/Services/EmailService.cs b/Services/EmailService.cs index 1dd39c3..0d007f7 100644 --- a/Services/EmailService.cs +++ b/Services/EmailService.cs @@ -69,6 +69,7 @@ public class EmailService : IEmail private static string BuildMailtoUri(EmailMessage? message) { var sb = new StringBuilder("mailto:"); + if (message == null) return sb.ToString(); // Add recipients if (message.To?.Count > 0) diff --git a/Services/SystemThemeService.cs b/Services/SystemThemeService.cs index 8030c85..b332ae1 100644 --- a/Services/SystemThemeService.cs +++ b/Services/SystemThemeService.cs @@ -56,7 +56,19 @@ public class SystemThemeService /// /// System colors based on the current theme. /// - public SystemColors Colors { get; private set; } + public SystemColors Colors { get; private set; } = new SystemColors + { + Background = SKColors.White, + Surface = new SKColor(0xF5, 0xF5, 0xF5), + Primary = new SKColor(0x21, 0x96, 0xF3), + OnPrimary = SKColors.White, + Text = new SKColor(0x21, 0x21, 0x21), + TextSecondary = new SKColor(0x75, 0x75, 0x75), + Border = new SKColor(0xE0, 0xE0, 0xE0), + Divider = new SKColor(0xE0, 0xE0, 0xE0), + Error = new SKColor(0xF4, 0x43, 0x36), + Success = new SKColor(0x4C, 0xAF, 0x50) + }; private FileSystemWatcher? _settingsWatcher; diff --git a/Services/SystemTrayService.cs b/Services/SystemTrayService.cs index a965dbf..0369542 100644 --- a/Services/SystemTrayService.cs +++ b/Services/SystemTrayService.cs @@ -101,7 +101,7 @@ public class SystemTrayService : IDisposable _ = ShowAsync(); } - private async Task TryYadTray() + private Task TryYadTray() { try { @@ -118,7 +118,7 @@ public class SystemTrayService : IDisposable }; _trayProcess = Process.Start(startInfo); - if (_trayProcess == null) return false; + if (_trayProcess == null) return Task.FromResult(false); // Start reading output for menu clicks _ = Task.Run(async () => @@ -137,11 +137,11 @@ public class SystemTrayService : IDisposable catch { } }); - return true; + return Task.FromResult(true); } catch { - return false; + return Task.FromResult(false); } } diff --git a/Services/X11InputMethodService.cs b/Services/X11InputMethodService.cs index 5cc3bbb..567fd98 100644 --- a/Services/X11InputMethodService.cs +++ b/Services/X11InputMethodService.cs @@ -27,7 +27,6 @@ public class X11InputMethodService : IInputMethodService, IDisposable private XIMProc? _preeditDoneCallback; private XIMProc? _preeditDrawCallback; private XIMProc? _preeditCaretCallback; - private XIMProc? _commitCallback; public bool IsActive => _isActive; public string PreEditText => _preEditText; diff --git a/Views/SkiaEditor.cs b/Views/SkiaEditor.cs index 086c0a5..a8c4914 100644 --- a/Views/SkiaEditor.cs +++ b/Views/SkiaEditor.cs @@ -982,6 +982,7 @@ public class SkiaEditor : SkiaView { base.OnFocusLost(); SkiaVisualStateManager.GoToState(this, SkiaVisualStateManager.CommonStates.Normal); + Completed?.Invoke(this, EventArgs.Empty); } #region Selection and Clipboard diff --git a/Views/SkiaImage.cs b/Views/SkiaImage.cs index 06fb158..101b957 100644 --- a/Views/SkiaImage.cs +++ b/Views/SkiaImage.cs @@ -84,7 +84,7 @@ public class SkiaImage : SkiaView !_pendingSvgReload) { _pendingSvgReload = true; - ReloadSvgDebounced(); + _ = ReloadSvgDebounced(); } } } @@ -427,7 +427,7 @@ public class SkiaImage : SkiaView { _lastArrangedBounds = bounds; Console.WriteLine($"[SkiaImage] Arrange detected larger bounds: {width}x{height} vs loaded {_svgLoadedWidth}x{_svgLoadedHeight}"); - LoadSvgAtSizeAsync(_currentFilePath, width, height); + _ = LoadSvgAtSizeAsync(_currentFilePath, width, height); } } } diff --git a/Views/SkiaShell.cs b/Views/SkiaShell.cs index 4ff629f..73746f6 100644 --- a/Views/SkiaShell.cs +++ b/Views/SkiaShell.cs @@ -693,7 +693,7 @@ public class SkiaShell : SkiaLayoutView } SetCurrentContent(root.Content); - Title = root.Title; + Title = root.Title ?? string.Empty; Invalidate(); } diff --git a/Views/SkiaWebView.cs b/Views/SkiaWebView.cs index d4abfe1..c191310 100644 --- a/Views/SkiaWebView.cs +++ b/Views/SkiaWebView.cs @@ -759,6 +759,11 @@ public class SkiaWebView : SkiaView public void LoadHtml(string html, string? baseUrl = null) { Console.WriteLine($"[WebView] LoadHtml called, html length: {html?.Length ?? 0}"); + if (string.IsNullOrEmpty(html)) + { + Console.WriteLine("[WebView] Cannot load HTML - html is null or empty"); + return; + } if (!_isInitialized) Initialize(); if (_webView == IntPtr.Zero || _webkitLoadHtml == null) { @@ -869,6 +874,7 @@ public class SkiaWebView : SkiaView public void ShowNativeWindow() { + if (_isEmbedded) return; // Already embedded if (!_isInitialized) Initialize(); if (_gtkWindow == IntPtr.Zero) return; @@ -918,7 +924,15 @@ public class SkiaWebView : SkiaView if (gdkWindow != IntPtr.Zero) { _gtkX11Window = gdk3_x11_window_get_xid(gdkWindow); - Console.WriteLine($"[WebView] GTK X11 window: {_gtkX11Window}"); + if (_gtkX11Window != IntPtr.Zero) + { + _isProperlyReparented = true; + Console.WriteLine($"[WebView] GTK X11 window: {_gtkX11Window} (reparented successfully)"); + } + else + { + Console.WriteLine($"[WebView] GTK X11 window: failed to get XID"); + } } PositionUsingGtk(); @@ -1073,13 +1087,20 @@ public class SkiaWebView : SkiaView } catch { } - int offsetX = 0, offsetY = 0; - int screenX = destX + (int)Bounds.Left - offsetX; - int screenY = destY + (int)Bounds.Top - offsetY; + // Track main window position changes + bool mainWindowMoved = destX != _lastMainX || destY != _lastMainY; + if (mainWindowMoved) + { + _lastMainX = destX; + _lastMainY = destY; + } + + int screenX = destX + (int)Bounds.Left; + int screenY = destY + (int)Bounds.Top; int width = Math.Max(100, (int)Bounds.Width); int height = Math.Max(100, (int)Bounds.Height); - if (Math.Abs(screenX - _lastPosX) > 2 || Math.Abs(screenY - _lastPosY) > 2 || + if (mainWindowMoved || Math.Abs(screenX - _lastPosX) > 2 || Math.Abs(screenY - _lastPosY) > 2 || Math.Abs(width - _lastWidth) > 2 || Math.Abs(height - _lastHeight) > 2) { Console.WriteLine($"[WebView] Move to ({screenX}, {screenY}), size ({width}x{height}), mainWin=({destX},{destY}), bounds=({Bounds.Left},{Bounds.Top})");