diff --git a/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj b/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj
index dd35532830..e0e773aaa6 100644
--- a/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj
+++ b/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj
@@ -55,6 +55,7 @@
+
diff --git a/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs b/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs
index 2aee41e617..81aac5e2dc 100644
--- a/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs
+++ b/src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs
@@ -49,10 +49,7 @@ namespace Avalonia.Gtk3
throw new NotImplementedException();
}
- public IPopupImpl CreatePopup()
- {
- throw new NotImplementedException();
- }
+ public IPopupImpl CreatePopup() => new PopupImpl();
diff --git a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs b/src/Gtk/Avalonia.Gtk3/Interop/Native.cs
index 0508dcadc1..736ec7e191 100644
--- a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs
+++ b/src/Gtk/Avalonia.Gtk3/Interop/Native.cs
@@ -59,7 +59,8 @@ namespace Avalonia.Gtk3.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
public delegate int gdk_window_get_origin(IntPtr gdkWindow, out int x, out int y);
-
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
+ public delegate void gdk_window_resize(IntPtr gtkWindow, int width, int height);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
@@ -77,6 +78,10 @@ namespace Avalonia.Gtk3.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_resize(IntPtr gtkWindow, int width, int height);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
+ public delegate void gtk_widget_set_size_request(IntPtr gtkWindow, int width, int height);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
+ public delegate void gtk_window_set_default_size(IntPtr gtkWindow, int width, int height);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_get_position(IntPtr gtkWindow, out int x, out int y);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_move(IntPtr gtkWindow, int x, int y);
@@ -128,6 +133,8 @@ namespace Avalonia.Gtk3.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
public delegate IntPtr gdk_window_get_pointer(IntPtr raw, out int x, out int y, out int mask);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
+ public delegate void gtk_window_set_geometry_hints(IntPtr window, IntPtr geometry_widget, ref GdkGeometry geometry, GdkWindowHints geom_mask);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
public delegate void gdk_window_invalidate_rect(IntPtr window, ref GdkRectangle rect, bool invalidate_children);
@@ -175,6 +182,9 @@ namespace Avalonia.Gtk3.Interop
public static D.gtk_widget_realize GtkWidgetRealize;
public static D.gtk_window_get_size GtkWindowGetSize;
public static D.gtk_window_resize GtkWindowResize;
+ public static D.gdk_window_resize GdkWindowResize;
+ public static D.gtk_widget_set_size_request GtkWindowSetSizeRequest;
+ public static D.gtk_window_set_default_size GtkWindowSetDefaultSize;
public static D.gtk_window_get_position GtkWindowGetPosition;
public static D.gtk_window_move GtkWindowMove;
public static D.g_signal_connect_object GSignalConnectObject;
@@ -364,6 +374,7 @@ namespace Avalonia.Gtk3.Interop
public GdkWindowState new_window_state;
}
+ [StructLayout(LayoutKind.Sequential)]
unsafe struct GdkEventKey
{
public GdkEventType type;
@@ -392,4 +403,33 @@ namespace Avalonia.Gtk3.Interop
Focused = 128,
Ttiled = 256
}
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct GdkGeometry
+ {
+ gint min_width;
+ gint min_height;
+ gint max_width;
+ gint max_height;
+ gint base_width;
+ gint base_height;
+ gint width_inc;
+ gint height_inc;
+ gdouble min_aspect;
+ gdouble max_aspect;
+ gint win_gravity;
+ }
+
+ enum GdkWindowHints
+ {
+ GDK_HINT_POS = 1 << 0,
+ GDK_HINT_MIN_SIZE = 1 << 1,
+ GDK_HINT_MAX_SIZE = 1 << 2,
+ GDK_HINT_BASE_SIZE = 1 << 3,
+ GDK_HINT_ASPECT = 1 << 4,
+ GDK_HINT_RESIZE_INC = 1 << 5,
+ GDK_HINT_WIN_GRAVITY = 1 << 6,
+ GDK_HINT_USER_POS = 1 << 7,
+ GDK_HINT_USER_SIZE = 1 << 8
+ }
}
diff --git a/src/Gtk/Avalonia.Gtk3/PopupImpl.cs b/src/Gtk/Avalonia.Gtk3/PopupImpl.cs
new file mode 100644
index 0000000000..4cc01c625f
--- /dev/null
+++ b/src/Gtk/Avalonia.Gtk3/PopupImpl.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Avalonia.Gtk3.Interop;
+using Avalonia.Platform;
+
+namespace Avalonia.Gtk3
+{
+ class PopupImpl : TopLevelImpl, IPopupImpl
+ {
+ static IntPtr CreateWindow()
+ {
+ var window = Native.GtkWindowNew(GtkWindowType.Popup);
+ Native.GtkWindowSetSizeRequest(window, 1, 1);
+ Native.GtkWindowSetDefaultSize(window, 200, 200);
+
+ return window;
+ }
+
+ public PopupImpl() : base(CreateWindow())
+ {
+
+
+ }
+
+ public override Size ClientSize
+ {
+ get
+ {
+ return base.ClientSize;
+ }
+ set
+ {
+ Native.GtkWindowSetDefaultSize(GtkWidget, (int)value.Width, (int)value.Height);
+ base.ClientSize = value;
+ var size = ClientSize;
+ }
+ }
+ }
+}
diff --git a/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs b/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs
index aa0044328e..989a0584fa 100644
--- a/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs
+++ b/src/Gtk/Avalonia.Gtk3/TopLevelImpl.cs
@@ -281,7 +281,7 @@ namespace Avalonia.Gtk3
}
- public Size ClientSize
+ public virtual Size ClientSize
{
get
{
@@ -289,7 +289,13 @@ namespace Avalonia.Gtk3
Native.GtkWindowGetSize(GtkWidget, out w, out h);
return new Size(w, h);
}
- set { Native.GtkWindowResize(GtkWidget, (int)value.Width, (int)value.Height); }
+ set
+ {
+ Native.GtkWindowResize(GtkWidget, (int)value.Width, (int)value.Height);
+ if (Native.GtkWidgetGetWindow(GtkWidget) == IntPtr.Zero)
+ Native.GtkWidgetRealize(GtkWidget);
+ Native.GdkWindowResize(Native.GtkWidgetGetWindow(GtkWidget), (int)value.Width, (int)value.Height);
+ }
}
public Point Position