0091: Where’s My Window?

This post, although not specifically requested by a reader, was inspired by a reader request…

Two things I appreciate in an application are when it remembers (from one session to the next):

  1. the size of its window, and
  2. its position.

This is especially convenient since I switched to a multi-monitor set-up. If I open an application or dialog, but then have to search the entire area of three large monitors to find it, I’m not just slowed down and put off, I’m dumped out of that zen-like coding head-space I’m so addicted to. And frankly, that’s grounds for dismissal in my book. I’ve fired several text editors for this violation of etiquette. I’ve even sworn off window managers for this.

So, since I don’t wanna come across as a hypocrite, I decided to come up with a GTK solution to these issues and over the next two posts, we’ll look at how to gather these statistics for future use.

So, Where is My Window, Anyway?

Results of this example:
Current example output
Current example output
Current example terminal output
Current example terminal output (click for enlarged view)

As it happens, GTK has a signal we can hook up to that gives us our application’s Window position. It goes by the name: configure-event.

The Constructor

Once you’ve got that little tidbit of knowledge, getting the signal/callback sorted out is no harder than any other. Let’s look at the TestRigWindow’s constructor:

this()
{
	super(title);
	addOnDestroy(&quitApp);
	addOnConfigure(&onConfigure); // this is it
		
	appBox = new AppBox(this);
	add(appBox);
		
	showAll();

	getPosition(xPosition, yPosition);
	showWindowStats();
		
} // this()

Just use addOnConfigure() to hook up the signal to the callback. The last two lines of the constructor don’t need to be there, but for demo purposes, they give us a report on the window’s position at start-up.

The Callback

Very much as straightforward as ever:

bool onConfigure(Event event, Widget widget)
{
	getPosition(xPosition, yPosition);
	writeln("The window is positioned at: x = ", xPosition, ", y = ", yPosition);
		
	return(false);
		
} // onConfigure()

In the real world, we wouldn’t be spewing all those lines of text into the shell. Instead, we’d have this callback sitting quietly in the weeds keeping track of our window’s position so that when the time comes, it can be saved out to a configuration file.

That getPosition() function is a method of the GTK Window that either directly, or indirectly, queries the operating system’s window manager.

Note: Something that isn’t obvious about this demo is that the onConfigure callback must return false, indicating that there are more signals to process, specifically the redraw signal. If this callback returns true, only the Window frame will be drawn. So, if you find your application in this state, there’s yer problem.

Now for a look at the TestRigWindow’s other function…

The showWindowStats() Function

This one is called from both the constructor and the quitApp() function, the first time it’s called is to give us a first look at window position. The second gives us the final position as we’re exiting the application. In the real world, this function would be replaced with another that writes out configuration data and there’d be yet another function that reads it back in when the application is restarted. That’s something we’ll get into at some point down the road, but for now, let’s just have a look at what we’ve got:

void showWindowStats()
{
	writeln("Window stats...");
	writeln("position: xPosition = ", xPosition, ", yPosition = ", yPosition);
		
} // showWindowStats()

This doesn’t gather any new information, just spits out what we already have stored in TestRigWindow properties. And that’s the best way to handle this type of thing… one function to gather the info, another to save it or, in this case, just report it.

Conclusion

Next time, we’ll carry on in this vein by exploring how to record the Window size as well. Until then, happy coding and make every little bit count.

Comments? Questions? Observations?

Did we miss a tidbit of information that would make this post even more informative? Let's talk about it in the comments.

You can also subscribe via RSS so you won't miss anything. Thank you very much for dropping by.

© Copyright 2023 Ron Tarrant