Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Window OnLoadComplete and GetPreferredSize improvements #2684

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 18 additions & 14 deletions src/Eto.Gtk/Forms/DialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public DialogHandler()
protected override void Initialize()
{
base.Initialize();
Control.Modal = true;
Control.KeyPressEvent += Connector.Control_KeyPressEvent;

var vbox = new EtoBox(Gtk.Orientation.Vertical, 0) { Handler = this };
Expand Down Expand Up @@ -96,14 +97,24 @@ public void ShowModal()
DisableAutoSizeUpdate++;
ReloadButtons();

Control.Modal = true;
Control.Child?.ShowAll();
if (!Control.IsRealized)
{
Control.Realize();
}
Control.QueueResize();
Callback.OnLoadComplete(Widget, EventArgs.Empty);

Control.ShowAll();
DisableAutoSizeUpdate--;

do
if (!WasClosed)
{
Control.Run();
} while (!WasClosed && !CloseWindow());
do
{
Control.Run();
} while (!WasClosed && !CloseWindow());
}

WasClosed = false;
Control.Hide();
Expand Down Expand Up @@ -185,20 +196,13 @@ public void RemoveDialogButton(bool positive, int index, Button item)
}
}

static readonly object WasClosedKey = new object();

bool WasClosed
{
get { return Widget.Properties.Get<bool>(WasClosedKey); }
set { Widget.Properties.Set(WasClosedKey, value); }
}

public override void Close()
{
if (CloseWindow())
if (Widget.Loaded && CloseWindow())
{
WasClosed = true;
Control.Hide();
Control.Unrealize();
WasClosed = true;
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/Eto.Gtk/Forms/FormHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public async void Show()
{
DisableAutoSizeUpdate++;
Control.Child.ShowAll();
Control.Realize();
Callback.OnLoadComplete(Widget, EventArgs.Empty);
if (ShowActivated || !Control.AcceptFocus)
Control.Show();
else
Expand Down
10 changes: 9 additions & 1 deletion src/Eto.Gtk/Forms/GtkControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public interface IGtkControl

void TriggerMouseEnterIfNeeded();
void TriggerMouseLeaveIfNeeded();

Control.ICallback Callback { get; }
}

public static class GtkControlExtensions
Expand Down Expand Up @@ -1150,8 +1152,12 @@ public virtual SizeF GetPreferredSize(SizeF availableSize)
{
if (!ContainerControl.IsRealized)
{
if (ContainerControl is Gtk.Window window)
window.Child.ShowAll();
else
ContainerControl.ShowAll();

ContainerControl.Realize();
ContainerControl.ShowAll();
}
#if GTK3
var requestMode = ContainerControl.RequestMode;
Expand Down Expand Up @@ -1236,6 +1242,8 @@ public bool IsMouseCaptured

Control IGtkControl.Widget => Widget;

Control.ICallback IGtkControl.Callback => Callback;

public void TriggerMouseEnterIfNeeded() => Connector.TriggerMouseEnterIfNeeded();
public void TriggerMouseLeaveIfNeeded() => Connector.TriggerMouseLeaveIfNeeded();

Expand Down
37 changes: 30 additions & 7 deletions src/Eto.Gtk/Forms/GtkWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public interface IGtkWindow
Gtk.Window Control { get; }

Size UserPreferredSize { get; }

Window.ICallback Callback { get; }
}

public class GtkShrinkableVBox : Gtk.Box
Expand Down Expand Up @@ -188,7 +190,7 @@ private void SetMinMax(Size? size)
#endif
Control.SetGeometryHints(Control, geom, Gdk.WindowHints.MinSize);
}


public bool Minimizable
{
Expand All @@ -215,7 +217,7 @@ public bool ShowInTaskbar
get { return !Control.SkipTaskbarHint; }
set { Control.SkipTaskbarHint = !value; }
}

public bool Closeable
{
get => Control.Deletable;
Expand Down Expand Up @@ -262,9 +264,9 @@ public WindowStyle WindowStyle
}
}
}

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

void SetTypeHint()
{
if (WindowStyle == WindowStyle.Default && (Minimizable || Maximizable))
Expand All @@ -284,7 +286,7 @@ public override Size Size
{
DisableAutoSizeUpdate++;
UserPreferredSize = value;

if (Widget.Loaded)
{
var diff = WindowDecorationSize;
Expand Down Expand Up @@ -447,7 +449,10 @@ public void HandleDeleteEvent(object o, Gtk.DeleteEventArgs args)

public void HandleShownEvent(object sender, EventArgs e)
{
Handler?.Callback.OnShown(Handler.Widget, EventArgs.Empty);
var h = Handler;
if (h == null || h.WasClosed)
return;
Application.Instance.AsyncInvoke(() => h.Callback.OnShown(Handler.Widget, EventArgs.Empty));
}

public void HandleWindowStateEvent(object o, Gtk.WindowStateEventArgs args)
Expand Down Expand Up @@ -615,12 +620,22 @@ public bool CloseWindow(Action<CancelEventArgs> closing = null)
return !args.Cancel;
}

static readonly object WasClosedKey = new object();

protected bool WasClosed
{
get { return Widget.Properties.Get<bool>(WasClosedKey); }
set { Widget.Properties.Set(WasClosedKey, value); }
}


public virtual void Close()
{
if (Widget.Loaded && CloseWindow())
{
Control.Hide();
Control.Unrealize();
WasClosed = true;
}
}

Expand Down Expand Up @@ -797,7 +812,7 @@ public void BringToFront()
if (WindowState == WindowState.Minimized)
Control.Present();
}

Control.GetWindow()?.Raise();
}

Expand Down Expand Up @@ -868,13 +883,21 @@ Size WindowDecorationSize
{
get
{
if (!Control.IsRealized)
{
Control.Child?.ShowAll();
Control.Realize();
}

var window = Control.GetWindow();
if (window == null)
return Size.Empty;
return window.FrameExtents.Size.ToEto() - Control.Allocation.Size.ToEto();
}
}

Window.ICallback IGtkWindow.Callback => Callback;

bool isInvalidated;

internal void PerformResize()
Expand Down
4 changes: 4 additions & 0 deletions src/Eto.Mac/Forms/DialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ bool ShowAttached

public virtual void ShowModal()
{
Control.LayoutIfNeeded();
Callback.OnLoadComplete(Widget, EventArgs.Empty);
MacView.InMouseTrackingLoop = false;
session = null;
EnsureOwner();
Expand All @@ -160,6 +162,8 @@ public virtual void ShowModal()

public virtual Task ShowModalAsync()
{
Control.LayoutIfNeeded();
Callback.OnLoadComplete(Widget, EventArgs.Empty);
MacView.InMouseTrackingLoop = false;
var tcs = new TaskCompletionSource<bool>();
session = null;
Expand Down
2 changes: 2 additions & 0 deletions src/Eto.Mac/Forms/FormHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ protected override void Initialize()

public virtual void Show()
{
Control.LayoutIfNeeded();
Callback.OnLoadComplete(Widget, EventArgs.Empty);
var visible = Control.IsVisible;
if (ShowActivated)
{
Expand Down
10 changes: 9 additions & 1 deletion src/Eto.Mac/Forms/MacView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1343,12 +1343,20 @@ static void FireOnShown(Control control)
// don't use GetMacViewHandler() extension, as that will trigger OnShown for themed controls, which will
// trigger Shown multiple times for the same themed control
var handler = control.Handler as IMacViewHandler;
handler?.Callback.OnShown(control, EventArgs.Empty);
var isWindow = control is Window;

// Parent controls get shown event first, then children
if (!isWindow)
handler?.Callback.OnShown(control, EventArgs.Empty);

foreach (var ctl in control.VisualControls)
{
FireOnShown(ctl);
}

// Window fires shown after all child controls
if (isWindow)
handler?.Callback.OnShown(control, EventArgs.Empty);
}

protected virtual void FireOnShown() => FireOnShown(Widget);
Expand Down
34 changes: 10 additions & 24 deletions src/Eto.Mac/Forms/MacWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,9 @@ protected override SizeF GetNaturalSize(SizeF availableSize)
naturalSize.Height = preferredClientSize.Value.Height;
}

return naturalSize;
var frame = Control.FrameRectFor(new RectangleF(naturalSize).ToNS());

return frame.Size.ToEto();
}

public NSMenu MenuBar
Expand Down Expand Up @@ -788,7 +790,7 @@ private void PerformAutoSize()
if (UserPreferredSize.Height != -1)
availableSize.Height = UserPreferredSize.Height - borderSize.Height;
var size = GetPreferredSize(availableSize);
SetContentSize(size.ToNS());
SetSize(size.ToNS());
}
}

Expand Down Expand Up @@ -1170,33 +1172,17 @@ protected virtual void PositionWindow()

#region IMacContainer implementation

void SetContentSize(CGSize contentSize)
void SetSize(CGSize newSize)
{
if (MinimumSize != Size.Empty)
{
contentSize.Width = (nfloat)Math.Max(contentSize.Width, MinimumSize.Width);
contentSize.Height = (nfloat)Math.Max(contentSize.Height, MinimumSize.Height);
newSize.Width = (nfloat)Math.Max(newSize.Width, MinimumSize.Width);
newSize.Height = (nfloat)Math.Max(newSize.Height, MinimumSize.Height);
}

if (Widget.Loaded)
{
var clientSize = ClientSize;
var diffy = clientSize.Height - (int)contentSize.Height;
var diffx = clientSize.Width - (int)contentSize.Width;
var frame = Control.Frame;
if (diffx != 0 || setInitialSize)
{
frame.Width -= diffx;
}
if (diffy != 0 || setInitialSize)
{
frame.Y += diffy;
frame.Height -= diffy;
}
Control.SetFrame(frame, true, AnimateSizeChanges);
}
else
Control.SetContentSize(contentSize);
var frame = Control.Frame;
frame.Size = newSize;
Control.SetFrame(frame, Widget.Loaded, AnimateSizeChanges);
}

#endregion
Expand Down
2 changes: 2 additions & 0 deletions src/Eto.WinForms/Forms/WindowHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ void Control_Load(object sender, EventArgs e)
Control.Size = size;
content.MinimumSize = content.MaximumSize = sd.Size.Empty;
ContainerContentControl.MinimumSize = sd.Size.Empty;

Callback.OnLoadComplete(Widget, EventArgs.Empty);
}

public override Size Size
Expand Down
12 changes: 12 additions & 0 deletions src/Eto.Wpf/Forms/DialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,18 @@ public void ShowModal()
if (owner != null && !owner.HasFocus)
owner.Focus();

if (Control.IsLoaded)
{
Callback.OnLoadComplete(Widget, EventArgs.Empty);
FireOnLoadComplete = false;
}
else
{
FireOnLoadComplete = true;
}

var _ = NativeHandle; // ensure SourceInitialized is called to get right size based on style flags

Control.ShowDialog();
WpfFrameworkElementHelper.ShouldCaptureMouse = false;

Expand Down
15 changes: 13 additions & 2 deletions src/Eto.Wpf/Forms/FormHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,21 @@ public FormHandler()
public virtual void Show()
{
Control.WindowStartupLocation = sw.WindowStartupLocation.Manual;
if (ApplicationHandler.Instance.IsStarted)
if (Control.IsLoaded)
{
Control.Show();
Callback.OnLoadComplete(Widget, EventArgs.Empty);
FireOnLoadComplete = false;
}
else
{
// We should trigger during the Control.Loaded event
FireOnLoadComplete = true;
}

var _ = NativeHandle; // ensure SourceInitialized is called to get right size based on style flags

if (ApplicationHandler.Instance.IsStarted)
Control.Show();
else
ApplicationHandler.Instance.DelayShownWindows.Add(Control);
WpfFrameworkElementHelper.ShouldCaptureMouse = false;
Expand Down
Loading
Loading