Skip to content

Commit

Permalink
Merge pull request #2261 from cwensley/curtis/window-closeable
Browse files Browse the repository at this point in the history
Add Window.Closeable to turn off the close button
  • Loading branch information
cwensley authored Jul 21, 2022
2 parents 7a13d62 + 1a614ec commit a85b467
Show file tree
Hide file tree
Showing 10 changed files with 268 additions and 50 deletions.
2 changes: 2 additions & 0 deletions src/Eto.Gtk/Forms/DialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public DialogHandler()

Resizable = false;
}

protected override Gdk.WindowTypeHint DefaultTypeHint => Gdk.WindowTypeHint.Dialog;

protected override void Initialize()
{
Expand Down
45 changes: 42 additions & 3 deletions src/Eto.Gtk/Forms/GtkWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ static class GtkWindow
internal static readonly object DisableAutoSizeUpdate_Key = new object();
internal static readonly object AutoSizePerformed_Key = new object();
internal static readonly object AutoSize_Key = new object();
internal static readonly object Minimizable_Key = new object();
internal static readonly object Maximizable_Key = new object();
}

public abstract class GtkWindow<TControl, TWidget, TCallback> : GtkPanel<TControl, TWidget, TCallback>, Window.IHandler, IGtkWindow
Expand Down Expand Up @@ -188,16 +190,39 @@ private void SetMinMax(Size? size)
#endif
Control.SetGeometryHints(Control, geom, Gdk.WindowHints.MinSize);
}


public bool Minimizable { get; set; }
public bool Minimizable
{
get => Widget.Properties.Get<bool>(GtkWindow.Minimizable_Key, true);
set
{
if (Widget.Properties.TrySet(GtkWindow.Minimizable_Key, value, true))
SetTypeHint();
}
}

public bool Maximizable { get; set; }
public bool Maximizable
{
get => Widget.Properties.Get<bool>(GtkWindow.Maximizable_Key, true);
set
{
if (Widget.Properties.TrySet(GtkWindow.Maximizable_Key, value, true))
SetTypeHint();
}
}

public bool ShowInTaskbar
{
get { return !Control.SkipTaskbarHint; }
set { Control.SkipTaskbarHint = !value; }
}

public bool Closeable
{
get => Control.Deletable;
set => Control.Deletable = value;
}

public bool Topmost
{
Expand Down Expand Up @@ -231,14 +256,28 @@ public WindowStyle WindowStyle
break;
case WindowStyle.Utility:
Control.Decorated = true;
Control.TypeHint = Gdk.WindowTypeHint.Utility;
break;
default:
throw new NotSupportedException();
}
SetTypeHint();
}
}
}

protected virtual Gdk.WindowTypeHint DefaultTypeHint => Gdk.WindowTypeHint.Normal;

void SetTypeHint()
{
if (WindowStyle == WindowStyle.Default && (Minimizable || Maximizable))
{
Control.TypeHint = DefaultTypeHint;
}
else
{
Control.TypeHint = Gdk.WindowTypeHint.Utility;
}
}

public override Size Size
{
Expand Down
36 changes: 35 additions & 1 deletion src/Eto.Mac/Forms/MacWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -542,9 +542,27 @@ static NSObject HandleWillReturnFieldEditor(NSWindow sender, NSObject client)

void SetButtonStates()
{
var button = Control.StandardWindowButton(NSWindowButton.ZoomButton);
NSButton button;
bool hideButtons = !Maximizable && !Minimizable;
button = Control.StandardWindowButton(NSWindowButton.ZoomButton);
if (button != null)
{
button.Hidden = hideButtons;
button.Enabled = Maximizable && Resizable;
}
button = Control.StandardWindowButton(NSWindowButton.MiniaturizeButton);
if (button != null)
{
button.Hidden = hideButtons;
button.Enabled = Minimizable;
}

button = Control.StandardWindowButton(NSWindowButton.CloseButton);
if (button != null)
{
button.Hidden = hideButtons && !Closeable;
button.Enabled = Closeable;
}
}

public bool Resizable
Expand Down Expand Up @@ -597,6 +615,22 @@ public bool ShowInTaskbar
get;
set;
}

public bool Closeable
{
get { return Control.StyleMask.HasFlag(NSWindowStyle.Closable); }
set
{
if (Control.RespondsToSelector(MacWindow.selSetStyleMask))
{
if (value)
Control.StyleMask |= NSWindowStyle.Closable;
else
Control.StyleMask &= ~NSWindowStyle.Closable;
SetButtonStates();
}
}
}

protected virtual NSWindowLevel TopmostWindowLevel => NSWindowLevel.PopUpMenu;

Expand Down
23 changes: 19 additions & 4 deletions src/Eto.WinForms/Forms/HwndFormHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,15 +230,30 @@ public bool ShowInTaskbar
}
set
{
var styleInt = Win32.GetWindowLong(Control, Win32.GWL.EXSTYLE);
var style = Win32.GetWindowLong(Control, Win32.GWL.EXSTYLE);
if (value)
styleInt |= (uint)Win32.WS_EX.APPWINDOW;
style |= (uint)Win32.WS_EX.APPWINDOW;
else
styleInt &= (uint)~Win32.WS_EX.APPWINDOW;
style &= (uint)~Win32.WS_EX.APPWINDOW;

Win32.SetWindowLong(Control, Win32.GWL.EXSTYLE, styleInt);
Win32.SetWindowLong(Control, Win32.GWL.EXSTYLE, style);
}
}

public virtual bool Closeable
{
get => ((Win32.WS)Win32.GetWindowLong(Control, Win32.GWL.STYLE)).HasFlag(Win32.WS.SYSMENU);
set
{
var style = Win32.GetWindowLong(Control, Win32.GWL.STYLE);
if (value)
style |= (uint)Win32.WS.SYSMENU;
else
style &= (uint)~Win32.WS.SYSMENU;
Win32.SetWindowLong(Control, Win32.GWL.STYLE, style);
}
}


public bool Topmost
{
Expand Down
52 changes: 48 additions & 4 deletions src/Eto.WinForms/Forms/WindowHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class WindowHandler : Window.IWindowHandler
{
internal static readonly object MovableByWindowBackground_Key = new object();
internal static readonly object IsClosing_Key = new object();
internal static readonly object Closeable_Key = new object();

public Window FromPoint(PointF point)
{
Expand Down Expand Up @@ -272,6 +273,8 @@ public override void AttachEvent(string id)
{
oldState = Control.WindowState;
Callback.OnWindowStateChanged(Widget, EventArgs.Empty);
if (!Closeable)
SetSystemMenu();
}
};
break;
Expand Down Expand Up @@ -365,14 +368,55 @@ public virtual bool Resizable

public virtual bool Maximizable
{
get { return Control.MaximizeBox; }
set { Control.MaximizeBox = value; }
get => Control.MaximizeBox;
set
{
if (Maximizable != value)
{
Control.MaximizeBox = value;
SetSystemMenu();
}
}
}

public virtual bool Minimizable
{
get { return Control.MinimizeBox; }
set { Control.MinimizeBox = value; }
get => Control.MinimizeBox;
set
{
if (Minimizable != value)
{
Control.MinimizeBox = value;
SetSystemMenu();
}
}
}

public virtual bool Closeable
{
get => Widget.Properties.Get<bool>(WindowHandler.Closeable_Key, true);
set
{
if (Widget.Properties.TrySet(WindowHandler.Closeable_Key, value, true))
{
// when the window is maximized/minimized the state of the close button is lost.
HandleEvent(Window.WindowStateChangedEvent);
SetSystemMenu();
}
}
}

void SetSystemMenu()
{
var useSystemMenu = Closeable || Minimizable || Maximizable;
Control.ControlBox = useSystemMenu;

var sysMenu = Win32.GetSystemMenu(NativeHandle, false);
if (sysMenu != IntPtr.Zero)
{
var closeFlags = Closeable ? Win32.MF.BYCOMMAND : Win32.MF.GRAYED;
Win32.EnableMenuItem(sysMenu, Win32.SC.CLOSE, closeFlags);
}
}

public virtual bool ShowInTaskbar
Expand Down
47 changes: 33 additions & 14 deletions src/Eto.WinForms/Win32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ public enum SW
SHOWDEFAULT = 10,
FORCEMINIMIZE = 11
}

[Flags]
public enum PRF
{
CHECKVISIBLE = 0x00000001,
NONCLIENT = 0x00000002,
CLIENT = 0x00000004,
ERASEBKGND = 0x00000008,
CHILDREN = 0x00000010
NONCLIENT = 0x00000002,
CLIENT = 0x00000004,
ERASEBKGND = 0x00000008,
CHILDREN = 0x00000010
}


Expand Down Expand Up @@ -186,9 +186,10 @@ public enum WM
DPICHANGED = 0x02E0,
NCCREATE = 0x0081,
NCLBUTTONDOWN = 0x00A1,
PRINT = 0x0317
PRINT = 0x0317,
SHOWWINDOW = 0x00000018
}

public enum HT
{
CAPTION = 0x2
Expand Down Expand Up @@ -285,7 +286,7 @@ public static MouseButtons GetMouseButtonWParam(IntPtr wParam)
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ShowWindow(IntPtr hWnd, SW nCmdShow);

[DllImport("user32.dll")]
public static extern IntPtr GetActiveWindow();

Expand Down Expand Up @@ -476,30 +477,48 @@ public struct GUITHREADINFO
public IntPtr hwndCaret;
public RECT rcCaret;
}

[DllImport("kernel32.dll")]
static extern uint GetCurrentThreadId();

public static bool GetInfo(out GUITHREADINFO lpgui, uint? threadId = null)
{
lpgui = new GUITHREADINFO();
lpgui.cbSize = Marshal.SizeOf(lpgui);

return GetGUIThreadInfo(threadId ?? GetCurrentThreadId(), ref lpgui);
}

public static IntPtr GetThreadFocusWindow(uint? threadId = null)
{
if (!GetInfo(out var info, threadId))
return IntPtr.Zero;

return info.hwndFocus;
}

[DllImport("gdi32.dll")]
public static extern bool OffsetWindowOrgEx(IntPtr hdc, int nXOffset, int nYOffset, ref POINT lpPoint);

[DllImport("user32.dll")]
public static extern IntPtr WindowFromPoint(POINT lpPoint);


[DllImport("user32.dll")]
public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
public static extern bool EnableMenuItem(IntPtr hMenu, SC uIDEnableItem, MF uEnable);

[Flags]
public enum MF : uint
{
BYCOMMAND = 0x00000000,
GRAYED = 0x00000001
}

public enum SC : uint
{
CLOSE = 0xF060
}
}
}
12 changes: 9 additions & 3 deletions src/Eto.Wpf/Forms/DialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ public DialogHandler(sw.Window window)
{
Control = window;
Control.ShowInTaskbar = false;
Resizable = false;
Minimizable = false;
Maximizable = false;
Control.PreviewKeyDown += Control_PreviewKeyDown;

dockMain = new swc.DockPanel();
Expand All @@ -34,6 +31,15 @@ public DialogHandler(sw.Window window)
gridButtons.Margin = new sw.Thickness();
}

protected override void Initialize()
{
base.Initialize();

Resizable = false;
Minimizable = false;
Maximizable = false;
}

public override void SetContainerContent(sw.FrameworkElement content)
{
this.content.Children.Add(dockMain);
Expand Down
Loading

0 comments on commit a85b467

Please sign in to comment.