Open artificiel opened 1 year ago
Maybe I should open a separate issue / feature request
I was wondering a way of handling new windows without instancing new ofApp for each window, because most of the time I'll be only sharing a texture in fullscreen windows. I even tried to make a new window from scratch in GLFW or try different oldschool fullscreen addons for macOS.
My personal guess is ofAppGLFWWindow grew strange over time (old code for old platforms) and has some hacky solutions that maybe not needed anymore, like nFramesSinceWindowResized < 3
but it is really hard to test things in all platforms.
One thing I would start testing if I had more time in previous project, was testing multiple windows as a separate functionality, like an addon or a modified OF Core to test and prototyping ignoring ofAppGLFWWindow heritage.
I think what you describe is parallel to the native fullscreen option.
currently with your "lightweight" windows, what happens if you fullscreen them with the window bar green button? and what macOS version are you running? and are you running with "distinct spaces" enabled?
I was wondering a way of handling new windows without instancing new ofApp for each window
@dimitre - def a separate issue and have solution for you - we use a similar pattern 🙂
@artificiel Im always disabling displays have separate spaces and using macOS 13.6 now. I never use green button but if I do they animate to position (I personally don't use much fullscreen in macos, I think the animations are dizzy and have flickering in menus, they feel clumsy here using a second display).
but I like very much the framerate consistency improvements you seen in your tests. Maybe it explain some difficulties I had over the years like: a consistent stroboscopic effect using ofGetFrameNum(), a consistent bpm master clock without using timing from audio buffer, and maybe even the ofGetFrameRate stuttering visible when we draw actual frameRate on screen. (much more pronounced on macOS than windows or linux)
I am all for the overall improvements. What should not be lost, IMO, is the flexibility of the current method for dealing with fullscreen + multiple monitors.
Also, I would say there isn't really a need for a special extra function. I would suggest rather adding an enum or set of enums to change default behavior of the existing ofFullscreen()
, maybe C-flag winds modification flash which can be or-ed together? Then it's easier to add addtional options in the future for platform-specific stuff.
@dimitre sort of off topic, but typically what we do is use ofApp for all windows and just have an extra draw function and sometimes keypress function for the render window.
ie in ofApp::setup
// setup the render window //
renderWin = ofCreateWindow(rsettings);
if (renderWin) {
ofAddListener(renderWin->events().draw, this, &ofApp::onRenderWindowDraw);
ofAddListener(renderWin->events().keyPressed, this, &ofApp::onRenderWindowKeyPressed);
ofAddListener(renderWin->events().keyReleased, this, &ofApp::onRenderWindowKeyReleased);
}
This is somewhat simplified but I think you could have an unlimited number of windows using the onRenderWindowDraw
you would just want to make sure you remove the listener when the window is closed.
@dimitre you say:
and maybe even the ofGetFrameRate stuttering visible when we draw actual frameRate on screen. (much more pronounced on macOS than windows or linux)
yes this is a definite GLFW problem since macOS13 (somehow circumvented by macOS14 game mode). and notwithstanding that specific bug, it is what I'm proposing to fix with https://github.com/openframeworks/openFrameworks/issues/7758 which is a useful cross-platform feature outside the context of the bug as it would make the calculations of phase more deterministic (whereas the regularity ofGetElapsedTimef() is subject to how update/draw gets scheduled/prioritized).
and:
I think the animations are dizzy and have flickering in menus, they feel clumsy here using a second display
there are many ways to customize the Spaces-based full screen UX (as Apple calls it "Presentation"), including providing the animation. however that gets more involved in native code, but maybe it's reasonable to design things so the transition is "instantaneous"? I personally do not care about the animation one way or the other, just the net result of enabling game mode.
@danomatika you mention:
there isn't really a need for a special extra function
which extra function are you referring to? the ofGetNativeFullScreenState()
to retrieve the state of native fullscreen? it has been quite helpful in disentangling the issues between GLFW sync bug and fullscreen native vs not native behaviour.
as for:
What should not be lost, IMO, is the flexibility of the current method for dealing with fullscreen + multiple monitors.
exactly, and that is why I'm suggesting an even more flexible approach with #7759 which is unobtrusive and useful (and opens the possibilities for one to build whatever logic they need about their monitor setup geometry without burdening OF with that complexity). as given as an example in the issue:
auto monitors = ofGetConnectedMonitorsRects();
auto r = monitors[1]; // control monitor presumably at index 0
for (size_t i = 2; i < monitors.size(); i++) r.growToInclude(monitors[i]);
ofSetFullScreen(r); // fullscreens on all but first monitor
of course that's unsafe code and needs bounds checks (will crash if you don't have 2 connected monitors) but it achieves @ofTheo's spec of having a control monitor + an OF window spanned fullscreen across N additional monitors, without knowing in advance their dimensions. this is currently not possible with ofSetFullscreen()
nor ofGLFWWindowSettings::multiMonitorFullScreen
. but that's cross-platform and disconnected from the issue of macOS fullscreen as it's not a scenario that the macOS fullscreen space-based presentations supports.
in order to pull maximum efficiency of macOS14+ game mode, "transparently" call
[cocoaWindow toggleFullScreen:nil]
on the window. (the proposed custom fullscreen would be exempted from this feature in order to escape from the macOS fullscreen limits).in addition to enabling game mode, this has the advantage of maintaining 1:1 with the native fullscreen triggers, which are:
tell application "System Events" to tell process "myFullScreenApp" to set value of attribute "AXFullScreen" of window 1 to true
).this means some care is needed to make sure the GLFW callbacks and cocao native full screen state are properly interpreted so OF "knows" it has been made fullscreen.
because GLFW is buggy only since macOS13 and game mode only available since macOS14+, and because perhaps some user apps have been tailored to specific expectations that are hard to know about, maybe not change the behaviour on previous macOS versions:
additional help function:
because the implementation is in a critical area of OF it might be pertinent to perform and test in parallel the different "fullscreen" issues? such as https://github.com/openframeworks/openFrameworks/issues/5158
note for users:
the Mission Control / Spaces Settings determines the behaviour of windows within a multi-monitor setup.
In other words:
so if you want to span across monitors you are outside native macOS native fullscreen territory and you need to use "no distinct spaces" and
ofSetWindowPosiiton
/Shape
withofGLFWWindowSettings.decorated = false
or a "custom rect" flavor of ofFullScreen(and until the vsync bug in GLFW is fixed or otherwise properly addressed, presumably fallback to something likeofGetExpectedPaintTimef
if you need to draw time-dependent things accurately).in all cases, as of macOS14, a single-monitor native fullscreen window plus the "game" app type in info.plist is required for game mode to kick in.