diff --git a/samples/ControlCatalog/MainWindow.xaml.cs b/samples/ControlCatalog/MainWindow.xaml.cs
index 413794dfa2..c2e8c0c082 100644
--- a/samples/ControlCatalog/MainWindow.xaml.cs
+++ b/samples/ControlCatalog/MainWindow.xaml.cs
@@ -1,6 +1,7 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
+using System;
namespace ControlCatalog
{
diff --git a/src/Avalonia.Controls/Platform/IWindowImpl.cs b/src/Avalonia.Controls/Platform/IWindowImpl.cs
index 69b946346e..37637b1624 100644
--- a/src/Avalonia.Controls/Platform/IWindowImpl.cs
+++ b/src/Avalonia.Controls/Platform/IWindowImpl.cs
@@ -31,7 +31,7 @@ namespace Avalonia.Platform
IDisposable ShowDialog();
///
- /// Enables of disables system window decorations (title bar, buttons, etc)
+ /// Enables or disables system window decorations (title bar, buttons, etc)
///
void SetSystemDecorations(bool enabled);
@@ -39,5 +39,10 @@ namespace Avalonia.Platform
/// Sets the icon of this window.
///
void SetIcon(IWindowIconImpl icon);
+
+ ///
+ /// Enables or disables the taskbar icon
+ ///
+ void ShowTaskbarIcon(bool value);
}
}
diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs
index 46c625cc4c..9c0245a714 100644
--- a/src/Avalonia.Controls/Window.cs
+++ b/src/Avalonia.Controls/Window.cs
@@ -61,11 +61,17 @@ namespace Avalonia.Controls
AvaloniaProperty.Register(nameof(SizeToContent));
///
- /// Enables of disables system window decorations (title bar, buttons, etc)
+ /// Enables or disables system window decorations (title bar, buttons, etc)
///
public static readonly StyledProperty HasSystemDecorationsProperty =
AvaloniaProperty.Register(nameof(HasSystemDecorations), true);
-
+
+ ///
+ /// Enables or disables the taskbar icon
+ ///
+ public static readonly StyledProperty ShowInTaskbarProperty =
+ AvaloniaProperty.Register(nameof(ShowInTaskbar), true);
+
///
/// Defines the property.
///
@@ -92,6 +98,8 @@ namespace Avalonia.Controls
HasSystemDecorationsProperty.Changed.AddClassHandler(
(s, e) => s.PlatformImpl?.SetSystemDecorations((bool) e.NewValue));
+ ShowInTaskbarProperty.Changed.AddClassHandler((w, e) => w.PlatformImpl?.ShowTaskbarIcon((bool)e.NewValue));
+
IconProperty.Changed.AddClassHandler((s, e) => s.PlatformImpl?.SetIcon(((WindowIcon)e.NewValue).PlatformImpl));
}
@@ -152,7 +160,7 @@ namespace Avalonia.Controls
}
///
- /// Enables of disables system window decorations (title bar, buttons, etc)
+ /// Enables or disables system window decorations (title bar, buttons, etc)
///
///
public bool HasSystemDecorations
@@ -160,6 +168,16 @@ namespace Avalonia.Controls
get { return GetValue(HasSystemDecorationsProperty); }
set { SetValue(HasSystemDecorationsProperty, value); }
}
+
+ ///
+ /// Enables or disables the taskbar icon
+ ///
+ ///
+ public bool ShowInTaskbar
+ {
+ get { return GetValue(ShowInTaskbarProperty); }
+ set { SetValue(ShowInTaskbarProperty, value); }
+ }
///
/// Gets or sets the minimized/maximized state of the window.
diff --git a/src/Gtk/Avalonia.Gtk/WindowImpl.cs b/src/Gtk/Avalonia.Gtk/WindowImpl.cs
index d8555b4e05..2c1826c509 100644
--- a/src/Gtk/Avalonia.Gtk/WindowImpl.cs
+++ b/src/Gtk/Avalonia.Gtk/WindowImpl.cs
@@ -6,11 +6,12 @@ using Gdk;
namespace Avalonia.Gtk
{
using Gtk = global::Gtk;
+
public class WindowImpl : TopLevelImpl, IWindowImpl
{
private Gtk.Window _window;
- private Gtk.Window Window => _window ?? (_window = (Gtk.Window) Widget);
-
+ private Gtk.Window Window => _window ?? (_window = (Gtk.Window)Widget);
+
public WindowImpl(Gtk.WindowType type) : base(new PlatformHandleAwareWindow(type))
{
Init();
@@ -29,8 +30,10 @@ namespace Avalonia.Gtk
_lastClientSize = ClientSize;
_lastPosition = Position;
}
+
private Size _lastClientSize;
private Point _lastPosition;
+
void OnConfigureEvent(object o, Gtk.ConfigureEventArgs args)
{
var evnt = args.Event;
@@ -44,7 +47,7 @@ namespace Avalonia.Gtk
}
var newPosition = new Point(evnt.X, evnt.Y);
-
+
if (newPosition != _lastPosition)
{
PositionChanged(newPosition);
@@ -107,10 +110,7 @@ namespace Avalonia.Gtk
Window.GetPosition(out x, out y);
return new Point(x, y);
}
- set
- {
- Window.Move((int)value.X, (int)value.Y);
- }
+ set { Window.Move((int)value.X, (int)value.Y); }
}
public IDisposable ShowDialog()
@@ -127,5 +127,7 @@ namespace Avalonia.Gtk
{
Window.Icon = ((IconImpl)icon).Pixbuf;
}
+
+ public void ShowTaskbarIcon(bool value) => Window.SkipTaskbarHint = !value;
}
-}
+}
\ No newline at end of file
diff --git a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs b/src/Gtk/Avalonia.Gtk3/Interop/Native.cs
index fb1a9955e3..ffc1d380a3 100644
--- a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs
+++ b/src/Gtk/Avalonia.Gtk3/Interop/Native.cs
@@ -38,6 +38,9 @@ namespace Avalonia.Gtk3.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_widget_hide(GtkWidget gtkWidget);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
+ public delegate void gtk_widget_show(GtkWidget gtkWidget);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_set_icon(GtkWindow window, Pixbuf pixbuf);
@@ -56,14 +59,17 @@ namespace Avalonia.Gtk3.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate IntPtr gtk_widget_get_screen(GtkWidget gtkWidget);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate IntPtr gtk_widget_set_double_buffered(GtkWidget gtkWidget, bool value);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate IntPtr gtk_widget_set_events(GtkWidget gtkWidget, uint flags);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
public delegate int gdk_screen_get_height(IntPtr screen);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)]
public delegate int gdk_screen_get_width(IntPtr screen);
@@ -72,10 +78,10 @@ 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)]
public delegate void gtk_widget_realize(GtkWidget gtkWidget);
@@ -86,33 +92,51 @@ namespace Avalonia.Gtk3.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_set_decorated(GtkWindow gtkWindow, bool decorated);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
+ public delegate void gtk_window_set_skip_taskbar_hint(GtkWindow gtkWindow, bool setting);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
+ public delegate bool gtk_window_get_skip_taskbar_hint(GtkWindow gtkWindow);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
+ public delegate void gtk_window_set_skip_pager_hint(GtkWindow gtkWindow, bool setting);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
+ public delegate bool gtk_window_get_skip_pager_hint(GtkWindow gtkWindow);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_get_size(GtkWindow gtkWindow, out int width, out int height);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_resize(GtkWindow gtkWindow, int width, int height);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_widget_set_size_request(GtkWidget widget, int width, int height);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_set_default_size(GtkWindow gtkWindow, int width, int height);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_get_position(GtkWindow gtkWindow, out int x, out int y);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_move(GtkWindow gtkWindow, int x, int y);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate GtkFileChooser gtk_file_chooser_dialog_new(Utf8Buffer title, GtkWindow parent, GtkFileChooserAction action, IntPtr ignore);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public unsafe delegate GSList* gtk_file_chooser_get_filenames(GtkFileChooser chooser);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_file_chooser_set_select_multiple(GtkFileChooser chooser, bool allow);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_file_chooser_set_filename(GtkFileChooser chooser, Utf8Buffer file);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_dialog_add_button(GtkDialog raw, Utf8Buffer button_text, GtkResponseType response_id);
-
-
-
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Cairo)]
public delegate CairoSurface cairo_image_surface_create(int format, int width, int height);
@@ -206,7 +230,6 @@ namespace Avalonia.Gtk3.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_clipboard_clear(IntPtr clipboard);
-
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.GdkPixBuf)]
public delegate IntPtr gdk_pixbuf_new_from_file(Utf8Buffer filename, out IntPtr error);
@@ -229,21 +252,27 @@ namespace Avalonia.Gtk3.Interop
public delegate bool gdk_pixbuf_save_to_bufferv(Pixbuf pixbuf, out IntPtr buffer, out IntPtr buffer_size,
Utf8Buffer type, IntPtr option_keys, IntPtr option_values, out IntPtr error);
-
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)]
public delegate void g_object_unref(IntPtr instance);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)]
public delegate void g_object_ref(GObject instance);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)]
public delegate ulong g_signal_connect_object(GObject instance, Utf8Buffer signal, IntPtr handler, IntPtr userData, int flags);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gobject)]
public delegate ulong g_signal_handler_disconnect(GObject instance, ulong connectionId);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Glib)]
public delegate ulong g_timeout_add(uint interval, timeout_callback callback, IntPtr data);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Glib)]
public delegate ulong g_free(IntPtr data);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Glib)]
public unsafe delegate void g_slist_free(GSList* data);
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gio)]
public delegate GInputStream g_memory_input_stream_new_from_data(IntPtr ptr, IntPtr len, IntPtr destroyCallback);
@@ -271,6 +300,10 @@ namespace Avalonia.Gtk3.Interop
public static D.gtk_window_set_decorated GtkWindowSetDecorated;
+ public static D.gtk_window_set_skip_taskbar_hint GtkWindowSetSkipTaskbarHint;
+ public static D.gtk_window_get_skip_taskbar_hint GtkWindowGetSkipTaskbarHint;
+ public static D.gtk_window_set_skip_pager_hint GtkWindowSetSkipPagerHint;
+ public static D.gtk_window_get_skip_pager_hint GtkWindowGetSkipPagerHint;
public static D.gtk_window_set_title GtkWindowSetTitle;
public static D.gtk_application_new GtkApplicationNew;
public static D.gtk_main_iteration GtkMainIteration;
@@ -280,6 +313,7 @@ namespace Avalonia.Gtk3.Interop
public static D.gtk_init GtkInit;
public static D.gtk_window_present GtkWindowPresent;
public static D.gtk_widget_hide GtkWidgetHide;
+ public static D.gtk_widget_show GtkWidgetShow;
public static D.gdk_get_native_handle GetNativeGdkWindowHandle;
public static D.gtk_widget_get_window GtkWidgetGetWindow;
public static D.gtk_widget_get_scale_factor GtkWidgetGetScaleFactor;
@@ -314,8 +348,7 @@ namespace Avalonia.Gtk3.Interop
public static D.gtk_clipboard_request_text GtkClipboardRequestText;
public static D.gtk_clipboard_set_text GtkClipboardSetText;
public static D.gtk_clipboard_clear GtkClipboardRequestClear;
-
-
+
public static D.gtk_im_multicontext_new GtkImMulticontextNew;
public static D.gtk_im_context_filter_keypress GtkImContextFilterKeypress;
public static D.gtk_im_context_set_client_window GtkImContextSetClientWindow;
diff --git a/src/Gtk/Avalonia.Gtk3/WindowImpl.cs b/src/Gtk/Avalonia.Gtk3/WindowImpl.cs
index f083185a84..e6935c4f20 100644
--- a/src/Gtk/Avalonia.Gtk3/WindowImpl.cs
+++ b/src/Gtk/Avalonia.Gtk3/WindowImpl.cs
@@ -2,6 +2,7 @@
using Avalonia.Controls;
using Avalonia.Gtk3.Interop;
using Avalonia.Platform;
+using System.Runtime.InteropServices;
namespace Avalonia.Gtk3
{
@@ -59,6 +60,9 @@ namespace Avalonia.Gtk3
//Why do we even have that?
}
+ public void ShowTaskbarIcon(bool value) => Native.GtkWindowSetSkipTaskbarHint(GtkWidget, !value);
+
+
class EmptyDisposable : IDisposable
{
public void Dispose()
diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs
index 4a30d48878..72485379a7 100644
--- a/src/Windows/Avalonia.Win32/WindowImpl.cs
+++ b/src/Windows/Avalonia.Win32/WindowImpl.cs
@@ -750,5 +750,27 @@ namespace Avalonia.Win32
return (int)(ptr.ToInt64() & 0xffffffff);
}
+
+ public void ShowTaskbarIcon(bool value)
+ {
+ var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, -20);
+
+ style &= ~(UnmanagedMethods.WindowStyles.WS_VISIBLE);
+
+ style |= UnmanagedMethods.WindowStyles.WS_EX_TOOLWINDOW;
+ if (value)
+ style |= UnmanagedMethods.WindowStyles.WS_EX_APPWINDOW;
+ else
+ style &= ~(UnmanagedMethods.WindowStyles.WS_EX_APPWINDOW);
+
+ WINDOWPLACEMENT windowPlacement = UnmanagedMethods.WINDOWPLACEMENT.Default;
+ if (UnmanagedMethods.GetWindowPlacement(_hwnd, ref windowPlacement))
+ {
+ //Toggle to make the styles stick
+ UnmanagedMethods.ShowWindow(_hwnd, ShowWindowCommand.Hide);
+ UnmanagedMethods.SetWindowLong(_hwnd, -20, (uint)style);
+ UnmanagedMethods.ShowWindow(_hwnd, windowPlacement.ShowCmd);
+ }
+ }
}
}