picoe / Eto

Cross platform GUI framework for desktop and mobile applications in .NET
Other
3.62k stars 329 forks source link

Gtk3 - Window.Resizable and Window.Maximizable have no effect. #1652

Open lgibson02 opened 4 years ago

lgibson02 commented 4 years ago

Title says it all really, this is a problem I observed today while testing under GTK.

Expected Behavior

When setting Resizable to false it is expected that the window should no longer be resizable by the user. Setting Maximizable to false should also prevent the user from maximizing the window.

Actual Behavior

Neithier properties have any effect.

Steps to Reproduce the Problem

  1. Use demonstration code below.
  2. Observe window is still resizable and maximize button is still allowed.

Code that Demonstrates the Problem

using Eto.Forms;
using Eto.Drawing;

namespace EtoGtkResizeTest {
    public partial class MainForm : Form {
        public MainForm() {
            Title = "My Eto Form";
            ClientSize = new Size(400, 350);
            Resizable = false;
            Maximizable = false;

            Content = new StackLayout {
                Padding = 10,
                Items = {
                    "Hello World!"
        }
            };
        }
    }
}

Specifications

lgibson02 commented 4 years ago

Is this project dead? This seems like a really basic issue.

cwensley commented 4 years ago

Hey @lgibson02, thanks for reporting the issue. The problem with this feature is that sizing is usually completely up to the window manager in linux and it is complicated to implement correctly in GTK. That being said it certainly could be improved upon.

btw, asking if a project is dead is not very constructive.

lgibson02 commented 4 years ago

@cwensley This isn't something that I've looked into too much but are you not able to just use the Resizable property in Gtk.Window? Here: http://docs.go-mono.com/?link=P%3aGtk.Window.Resizable.

Asking if this project is dead is a fair question when it takes two weeks to get a response on a bug report. I'll leave it at that though.

cwensley commented 4 years ago

Thanks for the suggestion, but simply just using the property resets the size of the window to the preferred size instead of what you have set it to, which is different than what you'd expect. Thus my "it's complicated" comment.

BTW, two weeks is not a long time for a free service. Also, please be cognizant of the global situation.

ManuelHu commented 4 years ago

Apparently, setting Control.Resizable in GtkWindow.Resizable works, at least on my machine (Ubuntu 20.04). Also when setting it while running, it does not change the window size.

This is the change I made to https://github.com/picoe/Eto/blob/develop/src/Eto.Gtk/Forms/GtkWindow.cs#L143:

public bool Resizable
{
    get { return resizable; }
    set
    {
        containerBox.Resizable = value;
        Control.Resizable = value; // This line is new
        resizable = value;
        SetMinMax(null);
    }
}

However, I didn't find any easy and fully working way to disallow maximization or minimization.

joshua-software-dev commented 4 years ago

This is the hacky workaround I used without modifying the library code that should work for stopping resizing in simple cases:

public class ResizeableForm : Form
{
    public delegate void IsResizableChanged(ResizeableForm sender, bool value);
    public static event IsResizableChanged IsResizableChangeEvent;

    protected bool IsResizable
    {
        get => Resizable;
        set
        {
            Resizable = value;
            IsResizableChangeEvent?.Invoke(this, value);
        }
    }
}

public class ExampleForm : ResizeableForm
{
    public ExampleForm()
    {
        IsResizable = false;
    }
}

then in your GTK Program.cs:

internal static class MainClass
{
    private static void ResizableFixer(ResizeableForm sender, bool value)
    {
        var refControl = sender.Handler.GetType().GetProperty("Control").GetValue(sender.Handler, null);
        var resizeProp = refControl.GetType().GetProperty("Resizable");
        resizeProp.SetValue(refControl, value, null);
    }

    [STAThread]
    public static void Main(string[] args)
    {
        ResizeableForm.IsResizableChangeEvent += ResizableFixer;
        new Application(Eto.Platforms.Gtk).Run(new MainForm());
    }
}

This is liable to break with future updates, but it works for the moment. Looking forward to a better method but for those who need something right now, this worked for me.

cwensley commented 3 years ago

Although Maximizable and Minimizable still do basically nothing in Gtk (because in Gtk you don't have control over that apparently), but Resizable has been implemented with #1930 while still allowing you to set preferred width/height/etc.