Custom window manager MacOS with multiple windows.
Posted: 29 Sep 2021, 23:48
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().