SocketEx.cs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. using Avalonia;
  2. using Avalonia.X11;
  3. using Gdk;
  4. using Color = Cairo.Color;
  5. namespace XEmbedSample;
  6. public class AvaloniaXEmbedGtkSocket : Gtk.Socket
  7. {
  8. private readonly RGBA _backgroundColor;
  9. private XEmbedPlug? _avaloniaPlug;
  10. public AvaloniaXEmbedGtkSocket(RGBA backgroundColor)
  11. {
  12. _backgroundColor = backgroundColor;
  13. }
  14. private object? _content;
  15. public object? Content
  16. {
  17. get => _content;
  18. set
  19. {
  20. _content = value;
  21. if (_avaloniaPlug != null)
  22. _avaloniaPlug.Content = _content;
  23. }
  24. }
  25. protected override void OnRealized()
  26. {
  27. base.OnRealized();
  28. _avaloniaPlug ??= XEmbedPlug.Create();
  29. _avaloniaPlug.ScaleFactor = ScaleFactor;
  30. _avaloniaPlug.BackgroundColor = Avalonia.Media.Color.FromRgb((byte)(_backgroundColor.Red * 255),
  31. (byte)(_backgroundColor.Green * 255),
  32. (byte)(_backgroundColor.Blue * 255)
  33. );
  34. _avaloniaPlug.Content = _content;
  35. ApplyInteractiveResize();
  36. AddId((ulong)_avaloniaPlug.Handle);
  37. }
  38. void ApplyInteractiveResize()
  39. {
  40. // This is _NOT_ a part of XEmbed, but allows us to have smooth resize
  41. GetAllocatedSize(out var rect, out _);
  42. var scale = ScaleFactor;
  43. _avaloniaPlug?.ProcessInteractiveResize(new PixelSize(rect.Width * scale, rect.Height * scale));
  44. }
  45. protected override void OnSizeAllocated(Rectangle allocation)
  46. {
  47. base.OnSizeAllocated(allocation);
  48. Display.Default.Sync();
  49. ApplyInteractiveResize();
  50. }
  51. protected override void OnDestroyed()
  52. {
  53. _avaloniaPlug?.Dispose();
  54. _avaloniaPlug = null;
  55. base.OnDestroyed();
  56. }
  57. }