mono / xwt

A cross-platform UI toolkit for creating desktop applications with .NET and Mono
MIT License
1.36k stars 241 forks source link

Window position cannot be properly set #257

Open ksigne opened 10 years ago

ksigne commented 10 years ago

This code Xwt.Window W = new Xwt.Window(); W.X = W.X; W.Y = W.Y; Makes window move to a random direction. It should be caused by inproper coordinate transformation.

slluis commented 10 years ago

You are getting the window position before it is shown and before setting any value to it. The value you'll get in this case is undefined, so no wonder it is being moved to a random position. Window should probably throw an exception in this case.

ksigne commented 10 years ago

You can find that window moves even if it is shown. I've made small shake animation and got problem with this.

My code and my solution hack: class Program { [STAThread] static void Main(string[] args) { Xwt.Application.Initialize(Xwt.ToolkitType.Gtk); Xwt.Window W = new Xwt.Window() { }; Xwt.Button B = new Xwt.Button("Animate"); W.Content = B; W.Show(); B.Clicked += (o, e) => {

region Костыль

//Авторы чего-то напутали в системах координат, в результате чего безобидный код W.X = W.X сдвигает окно на какое-то расстояние, разное для каждого окна. Маленький костыль исправляет ситуацию. Мелькание окна иногда проскакивает, иногда нет. double CurX = W.X, CurY = W.Y; W.X = CurX; W.Y = CurY; double DiffX = W.X - CurX, DiffY = W.Y - CurY; W.X = CurX - DiffX; W.Y = CurY - DiffY;

endregion

            W.Animate("", (X) =>
            {
                W.Location = new Point((CurX - DiffX) + 8 \* Math.Sin(20 \* X), (CurY - DiffY));
            }, length: 750, repeat: () => false);
        };
        Xwt.Application.Run();
    }
}

DavidKarlas commented 10 years ago

Abit better sample showing problem: It's very interesting effect on Gtk and not so intersting on Wpf but still visible.

using System;
using System.Diagnostics;
using System.Timers;
using Xwt;
using Xwt.Motion;
class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        Xwt.Application.Initialize(Xwt.ToolkitType.Gtk);
        Xwt.Window W = new Xwt.Window();
        W.X = 500;
        W.Y = 500;
        W.Show();
        Timer timer = new Timer(100);
        timer.Elapsed += new ElapsedEventHandler((o, e) =>
        {
            Application.Invoke(new Action(() =>
            {
                W.X = W.X;
                Debug.WriteLine("X:" + W.X + " Y:" + W.Y);
            }));
        });
        timer.Start();
        Xwt.Application.Run();
    }
}

Output:

X:516 Y:562
X:524 Y:593
X:532 Y:624
X:540 Y:655
X:548 Y:686
X:556 Y:717
X:564 Y:748
DavidKarlas commented 10 years ago

I reduced problem down to this GTK(pure GTK no XWT) app:

Anyone know why is XWT calling GdkWindow for getting current cordinates? in Xwt.GtkBackend.WindowFrameBackend.Bounds?

using System;
using Gtk;
using System.Timers;

public partial class MainWindow: Gtk.Window
{
    static  Timer timer;
    public MainWindow () : base (Gtk.WindowType.Toplevel)
    {
        timer = new Timer (100);
        timer.Elapsed += new ElapsedEventHandler ((o, ea) => {
            int x,y;
            GdkWindow.GetPosition(out x, out y);
            GdkWindow.Move(x,y);
        });
        timer.Start ();
    }
}

Problem is that GdkWindow.GetPosition or GdkWindow.GetOrigin returns current position + 8px.

DavidKarlas commented 10 years ago

I think there is still bug on GTK backend or was it fixed on GTK#?

slluis commented 10 years ago

Forgot about the GTK part. I don't think that's fixed. Reopening.

sevoku commented 9 years ago

Any progress on this?

sevoku commented 9 years ago

I've added a PR that hopefully fixes this for Gtk: #479 But i think we have an other issue with Window Bounds and Positions in: #480