Goldilocks Graphics Windows
QUESTION: I am looking for a platform independent way to create a large IDL graphics window. I want it to be nearly as large as the display, but not too large. I don't want it to hide behind window decorations like title bars, nor do I want it to appear behind task bars, tool bars, start bars, and other features on my monitor. I don't want it to be too small. I want to create the graphics window in a size that is “just right.” Do you have any suggestions for me.
ANSWER: Yes. Stop being so controlling. Live a little.
If by “platform independent” you mean code that works the same on Windows, UNIX, and Macintosh computers, I have just three words for you: “In your dreams!” This is one of those platform independent issues that drive software developers crazy.
You might think the problem could be solved by asking for the graphics screen size with the Device command, like this.
IDL> Device, Get_Screen_Size=theSize IDL> Print, theSize 1280 1024
Or, alternatively, by using the IDL library function Get_Screen_Size, like this.
IDL> theSize = Get_Screen_Size() IDL> Print, theSize 1280 1024
But, you would be wrong. These commands do, in fact, return the actual size of the display or monitor, but they don't return the size of the window you need. If you make a window this size, parts of it will be either off the display or will be behind other features in the window, like the task bar or tool bar. And, note too, that on Macintosh computers, you do not get the size of your monitor returned. Rather you get the size of your monitor, minus the part of the monitor taken up by the ever-present menu bar. Here is a typical result for Macintosh computers with a 1280 by 1024 monitor.
IDL> theSize = Get_Screen_Size() IDL> Print, theSize 1280 1002
Dick Jackson has proposed a solution for Windows computers, named GetPrimaryScreenSize.
FUNCTION GetPrimaryScreenSize, Exclude_Taskbar=exclude_Taskbar oMonInfo = Obj_New('IDLsysMonitorInfo') rects = oMonInfo -> GetRectangles(Exclude_Taskbar=exclude_Taskbar) pmi = oMonInfo -> GetPrimaryMonitorIndex() Obj_Destroy, oMonInfo Return, rects[[2, 3], pmi] END
When called with the Exclude_Taskbar keyword, it will return the correct window size for Windows computers. This keyword is ignored by both UNIX and Macintosh computers.
IDL> Print, GetPrimaryScreenSize(/EXCLUDE_TASKBAR) 1280 994
As it happens, the IDLsysMonitorInfo method is what the IDL library routine Get_Screen_Size uses to obtain the size of the monitor, although there is no option in this routine to set the Exclude_Taskbar keyword.
Unfortunately, for UNIX computers, including the Macintosh, there is no known method to get the proper window size programmatically. However, for UNIX computers, excluding Macintosh, you can get the proper window size if you create a window the size of the monitor, then check the !D.X_Size and !D.Y_Size system variables to see what these values are actually set to. They will be set to the size you are looking for!
;; UNIX computers, excluding the Macintosh. IDL> theSize = Get_Screen_Size() IDL> Print, theSize 1280 1024 IDL> Window, XSIZE=1280, YSIZE=1024 IDL> Print, !D.X_Size, !D.Y_Size 1278 944
Note that to use this solution in a program, you would have to open a window to find out what size window is required, then delete the window, then open a window of the correct size (probably after deleting the overly large window). This would cause a momentary window “flashing” as a large window was opened and deleted. An unfortunate artifact of the solution, but unavoidable.
For Macintosh computers, there is no known solution to this problem. There, you must simply resort to a “fudge factor” to estimate the size of the Macintosh dock. For many Macintosh computers, a fudge factor of 22 pixels works reasonably well.
Here is a function, named MaxWindowSize, that uses these methods to provide the maximum size of an unobscured graphics window.
Update for Mactintosh Users
Wayne Landman reports this interesting result in a Nov 3rd, 2012 IDL newsgroup post.
For the second time this week, I found a need to repeat an IDL command for it to take full effect. Below is the sample program on my Mac.pro testwin print,getprimaryscreensize() window,xsize=870,ysize=870,retain=2 print,!D.y_size,!D.y_vsize print,!D.y_size,!D.y_vsize return end
The output looks like this.IDL> testwin 1440 878 870 870 856 856
So when I first ask to print !D.y_vsize it returns 870, but when I immediately ask again it returns 856. This problem is avoided if I put any sort of wait statement after opening the window. It appears to take a finite time, after I ask IDL to open a window with a Ysize of 870 pixels, to realize that the toolbar is using up 22 pixels and adjust !Y.V_SIZE accordingly.
This delay is what may have caused the difficulty in getting the Mac useful screen size. My solution for getting the useful Mac screen size would now be the following.function getmacsize xy = get_screen_size() window,xsize=xy,ysize=xy,/free wait,0.01 out = [!D.x_vsize,!D.Y_vsize] wdelete,!D.window return,out end
Of course, this will give flashing but at least it will give the right answer.
Version of IDL used to prepare this article: IDL 8.0
Copyright © 2010 David W. Fanning
Written 25 October 2010
Last Updated 4 November 2012