Set fullscreen window size before "window-state-event" handler returns

Consider the following simple program:

// Compile with: g++ test.cpp `pkg-config --libs --cflags gtkmm-3.0`

#include <iostream>
#include <gtkmm/main.h>
#include <gtkmm/window.h>

class MainWindow : public Gtk::Window
{
	public:
		MainWindow()
		{
			this->set_title("Test");
			this->set_default_size(300, 300);

			this->signal_window_state_event().connect(sigc::mem_fun(*this, &MainWindow::fullscreen_state_changed));
		}

	private:
		bool fullscreen_state_changed(GdkEventWindowState *state)
		{
			if (state->changed_mask & Gdk::WINDOW_STATE_FULLSCREEN)
			{
				int width, height;
				this->get_size(width, height);

				std::cout << width << "x" << height << std::endl;

				return true;
			}

			return false;
		}
};

int main(int argc, char *argv[])
{
	Gtk::Main app(argc, argv);

	MainWindow window;

	Gtk::Main::run(window);
}

You’ll notice that as you change the fullscreen state (how to do this depends on your WM and its configuration, for me it’s Super+F), on the terminal the size of the previous state will be printed.

But what to do if you need the size of the current state? For example, what if you need to scale the picture to always fit the current window when the fullscreen state is changed? Please note that it is not enough to merely figure out the new size, what is needed is to actually change the current size so the rest of the program can “happen” naturally. (Maybe I can force new window size prematurely if I can find it out?) Otherwise it would be very hacky to attempt to make the rest of the code believe that the size of the window has changed when it actually hasn’t.

It sounds like you are not actually interested in the fullscreen state, but in size changes of the toplevel window. You can use the configure-event signal to track those.

Sorry, but I don’t know how to do that. I’ve tried various approaches to waiting for configure-event and then attempting to redraw but so far no luck.

Can someone show me how to do it properly?

Or maybe I am doing it properly and the problem is somewhere else? This is what I tried:

  • Using g_signal_connect() I connected configure-event to its handler and saved the returned gulong into a variable and blocked the handler with g_signal_handler_block(). Afterwards, in window-state-event handler, if I detected that the fullscreen state changed, I would unblock the configure-event handler with g_signal_handler_unblock(). configure-event handler would then redraw the drawing area and block itself again.

  • I would have configure-event handler unblocked the whole time, and I would also have it contain a static gboolean variable that holds the previous fullscreen state. Current fullscreen state is held in a global variable and properly updated by window-state-event. Then if configure-event handler finds that the previous state and the current state are different, it would redraw the drawing area.

  • Synthesis of the previous two: use both signal ID and static variable. I guess this is more safe but it also seems like a wrong way to do it (it’s too convoluted).

None of them seem like the right approaches, and really none of them worked. Though, to be honest, debugger does show that the redraw function is called at the right times and with proper information, but the actual redrawing simply doesn’t happen when going from fullscreen to normal. It does happen when going from normal to fullscreen, but that also happens without all this mess.