Questions regarding multiple windows (and possible bug?)

I just setup my app to use multiple windows, in my “main”, i create one window like this:

	ofGLFWWindowSettings settings;
	settings.setSize(1900, 1000);
	settings.resizable = false;
	shared_ptr<ofAppBaseWindow> editorWindow = ofCreateWindow(settings);

	shared_ptr<MainEditor> mainEditorSharedPtr = make_shared<MainEditor>();
	MainEditorWindow mainEditorWindow(mainEditorSharedPtr);
	mainEditorSharedPtr->attachObserver(mainEditorWindow);

	ofRunApp(editorWindow, mainEditorSharedPtr);
	settings.visible = false;
	editorWindow = ofCreateWindow(settings);
	ofRunMainLoop();

This parts works well, everything looks normal.
In my program, i created a “Command” that opens up a second window with a second “ofBaseApp”:

	settings.setSize(500, 500);

	shared_ptr<IconEditor> iconEditorSharedPtr = make_shared<IconEditor>(m_mainEditorPtr);
	shared_ptr<ofAppBaseWindow> temporaryWindow = ofCreateWindow(settings);

	m_iconEditorWindowPtr = new IconEditorWindow(iconEditorSharedPtr);
	iconEditorSharedPtr->attachObserver(*m_iconEditorWindowPtr);

	ofRunApp(temporaryWindow, iconEditorSharedPtr);

This window works well, except the text in my gui is replaced by rectangles:


The text of my main app is unaffected. I can correct this problem by using “setUseTTF(true)” on the ofxPanel of my “pop up” window. But then the problem switches to my main window:

Other questions:

I saw that it’s possible to set a window visibility to “false” in “ofGLFWWindowSettings settings”. It’s the only place i’ve found this option. Is it possible to give an already created “shared_ptr” a new "“ofGLFWWindowSettings settings”. My intention is to create both windows at startup and just hide/show my pop-up window when needed. Would be more simple i think.

I want to disable access to my main window as long as my pop up window is active. I can think of 3 ways to do that but i wasnt able to figure out how to code any of them…

  • I could force my pop up window to remain my “current window” as long as its opened.
  • I could disable all listeners on my main window, including the ones linked to “ofxButtons”, “ofxSliders”, etc.
  • I could completely hide my main window for as long as my pop up window is active.
1 Like

Hi, I think taht the fix for that is to share the gl instance when you create the window.
before creating temporaryWindow add the following line to settings.

settings.shareContextWith = editorWindow;

Let me know if that works.

1 Like

you can also create and destroy windows on the fly.

this is what I use on my ofxLineaDeTiempo addon.


shared_ptr<ofAppBaseWindow> TracksPanelController::displayOnNewWindow(const ofRectangle& windowShape, bool bShareCurrentContext)
{
	if(_ownedWindow  == nullptr)
	{
		ofGLFWWindowSettings settings;
		settings.setSize(windowShape.width, windowShape.height);
		settings.setPosition(windowShape.getPosition());
		settings.resizable = true;
		if(bShareCurrentContext) settings.shareContextWith = ofGetCurrentWindow();
		return displayOnNewWindow(settings);
	}
	return nullptr;
}


shared_ptr<ofAppBaseWindow> TracksPanelController::displayOnNewWindow(const ofGLFWWindowSettings& settings)
{
	if(_ownedWindow == nullptr)
	{
		_ownedWindow = ofCreateWindow(settings);
		_ownedWindow->setVerticalSync(false);
		_bAutoFill = true;
		setWindow(_ownedWindow.get());
		if(!hasView())
		{
			generateView();
		}
		
		
		auto w = dynamic_cast<ofAppGLFWWindow*>(_ownedWindow.get());
		if(w)
		{
			_ownedWindowExitListener = w->events().exit.newListener(this, &TracksPanelController::_ownedWindowExited);
		}
		
		return _ownedWindow;
	}
	return nullptr;
}

void TracksPanelController::_ownedWindowExited(ofEventArgs&)
{
	_currentWindow = nullptr;
	destroyView();
	_ownedWindow = nullptr;
	_ownedWindowExitListener.unsubscribe();
	
}

void TracksPanelController::closeWindow()
{
	if(_ownedWindow)
	{
		auto w = dynamic_cast<ofAppGLFWWindow*>(_ownedWindow.get());
		if(w)
		{
			w->setWindowShouldClose();
			ofEventArgs a;
			_ownedWindowExited(a);
		}
	}
}
1 Like

it does work, tks!

If i may, i have a few questions:

I start my main window in my “main.cpp”, but my second window from another object. I was able to pass the “shared_ptr” created in my main from an object to another to test your solution. But by doing so i created a lot of extra dependencies.

When running “ofRunApp(editorWindow, mainEditorSharedPtr)”, editorWindow must be stored somewhere. Is there a way to access that “somewhere”? :slight_smile:

Also, lets say i create my second window with this line:

ofRunApp(temporaryWindow, conEditorSharedPtr);

If i use “ofGetCurrentWindow()->setWindowShouldClose();” to close that second window, do you know if all trace of it is deleted from memory? Like if i open/close this window multiple time, am i creating a small memory leak? I’ve tried to follow the of source code to find an answer, but it’s not the easiest to follow, nor the most well documented ive seen…

Notice that in the code I posted I use
settings.shareContextWith = ofGetCurrentWindow(); thus no need to store the main window.
another option is to create

shared_ptr<ofAppBaseWindow> myWindow;/

inside your Maineditor class and then in main.cpp.


shared_ptr<ofAppBaseWindow> editorWindow = ofCreateWindow(settings);

	shared_ptr<MainEditor> mainEditorSharedPtr = make_shared<MainEditor>();
	MainEditorWindow mainEditorWindow(mainEditorSharedPtr);
	mainEditorSharedPtr->attachObserver(mainEditorWindow);
mainEditorSharedPtr->myWindow = editorWindow;

I think the previous answer applies as well.
As editorWindow is a shared_ptr you can have it in several different places and in all it will point to the same window.

If you use ofGetCurrentWindow it is a bit uncertain which is the current window, so I think that you should simply store resulting shared_ptr somewhere in your class.
There are no leaks if you open/close several windows, so far that you manage properly the shared_ptrs. (mostly avoid circular reeference). Besides that it will destroy properly and invalidate the shared_pointers, if any.
In the code you posted you used the new keyword and you did not delete that properly, which will give you a memory leak.
The easiet way I think is to use unique_ptr which ill dealocate properly upon its destruction.

1 Like

BIG tks for your help!

1 Like