Custom window manager MacOS with multiple windows.
Hi,
I'm making an application that will use multiple windows.
I got this working on Windows with my own window manager class.
To use this class i initialise windows as follows:
This way i can successfully display any window i want on the fly.
However when i try this on MacOS it doesn't work as aspected.
I initialize 1 window on MacOS like so:
Now when i call:
The "Render(Display display)" callback in WindowManager gets only invoked once.
And the screen stays black.
Also, if i try to initialise 2 windows on MacOS i get an error:
System.InvalidOperationException: Init has already been invoked; it can only be invoked once.
Init() get called multiple times on Appkit.NSApplication.Init().
I'm making an application that will use multiple windows.
I got this working on Windows with my own window manager class.
Code: Select all
#if NOESIS
using Noesis;
using NoesisApp;
#endif
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Managers
{
public class WindowManager
{
#if NOESIS
static List<Window> _windows = new List<Window>();
static List<Display> _displays = new List<Display>();
static List<RenderContext> _contexts = new List<RenderContext>();
static List<DateTime> _startTime = new List<DateTime>();
static WindowManager _instance;
T AddWindow<T>(T window) where T : Window
{
_windows.Add(window);
return window;
}
T AddContext<T>(T context) where T : RenderContext
{
_contexts.Add(context);
return context;
}
T AddDisplay<T>(T display) where T : Display
{
_displays.Add(display);
return display;
}
public static WindowManager Instance => _instance;
public WindowManager()
{
_instance = this;
}
public int WindowCount => _displays.Count;
public Action OnRender;
public void EnterMessageLoop(bool RunInBackGround)
{
_displays[0].EnterMessageLoop(false);
}
public void CreateWindow(Window window, Display display, RenderContext context)
{
Window _window = AddWindow(window);
Display _display = AddDisplay(display);
_display.SetResizeMode(ResizeMode.CanResize);
RenderContext _context = AddContext(context);
_context.Init(_display.NativeHandle, _display.NativeWindow, 1, true, false);
_window.Init(_display, _context, 1, false, true, false, 0, 0, 0, 0);
_display.Render += Render;
_display.Closed += OnClosed;
_display.Show();
_startTime.Add(DateTime.Now);
}
void Render(Display display)
{
for (int i = 0; i < _displays.Count; i++)
{
_windows[i].Render((DateTime.Now - _startTime[i]).TotalSeconds);
}
OnRender?.Invoke();
}
void OnClosed(Display display)
{
int index = _displays.IndexOf(display);
_displays.RemoveAt(index);
_windows.RemoveAt(index);
_contexts.RemoveAt(index);
_startTime.RemoveAt(index);
}
#endif
}
}
Code: Select all
WindowManager winManager = new WindowManager();
winManager.CreateWindow(new MainWindow(), new Win32Display(), new RenderContextWGL());
winManager.CreateWindow(new MainWindow(), new Win32Display(), new RenderContextWGL());
while (winManager.WindowCount > 0)
{
winManager.EnterMessageLoop(true);
}
GUI.Shutdown();
However when i try this on MacOS it doesn't work as aspected.
I initialize 1 window on MacOS like so:
Code: Select all
winManager.CreateWindow(new MainWindow(), new AppKitDisplay(), new RenderContextNSGL());
Code: Select all
winManager.EnterMessageLoop(true);
And the screen stays black.
Also, if i try to initialise 2 windows on MacOS i get an error:
System.InvalidOperationException: Init has already been invoked; it can only be invoked once.
Init() get called multiple times on Appkit.NSApplication.Init().
Re: Custom window manager MacOS with multiple windows.
We haven't tested the application framework with multiple windows. This is something we want to do sooner or later but for now, our examples do not require that and the application framework is the minimal set of features for the examples.
The source code is available and can be modified or you can even provide a different implementation. We can help you with the changes, just inspecting the code I see a few problems:
The source code is available and can be modified or you can even provide a different implementation. We can help you with the changes, just inspecting the code I see a few problems:
- Appkit.NSApplication.Init() should be invoked only once, from the static ctor instead of normal ctor
- EnterMessageLoop will only get messages for the first window, you need a mechanism to get also messages from the others. In windows this works because the messages are shared between windows of the same thread but it seems this is different on macOS.
Re: Custom window manager MacOS with multiple windows.
I'm now at a point where i can properly open 2 or more windows and close them 1 by 1 and the app will shut down nicely.
AppKitDisplay.cs i added:
in the "public AppKitDisplay()" function i added:
And in the "OnClose()":
Regards
AppKitDisplay.cs i added:
Code: Select all
private static int _windowCount = 0;
private static NSApplication _app;
private static bool _init = false;
Code: Select all
public AppKitDisplay()
{
if (!_init)
NSApplication.Init();
_init = true;
_windowCount++;
...............
}
Code: Select all
public void OnClosed()
{
IsClosed = true;
_windowCount--;
if (_windowCount == 0)
_app.Terminate(null);
Closed?.Invoke(this);
}
Re: Custom window manager MacOS with multiple windows.
Great, for the messages (EnterMessageLoop) I think you need to pull all window messages from the first window. I think one client modified the source to do that.
Re: Custom window manager MacOS with multiple windows.
The behaviour of messages seems to be the same on mac as it is in windows.
For instance: Only the currently active window gets the user input.
Also had to modify Window.cs to actually take ratina display scaling into account which is 2 instead of 1.
I did fork the Managed repo (Wyvernius) and changes i made are under MacOSMultiWindow
For instance: Only the currently active window gets the user input.
Also had to modify Window.cs to actually take ratina display scaling into account which is 2 instead of 1.
I did fork the Managed repo (Wyvernius) and changes i made are under MacOSMultiWindow
Who is online
Users browsing this forum: Semrush [Bot] and 92 guests