GUI/Maximum window dimensions

From Rosetta Code
< GUI
Task
GUI/Maximum window dimensions
You are encouraged to solve this task according to the task description, using any language you may know.

The task is to determine the maximum height and width of a window that can fit within the physical display area of the screen without scrolling.

This is effectively the screen size (not the total desktop area, which could be bigger than the screen display area) in pixels minus any adjustments for window decorations and menubars.

The idea is to determine the physical display parameters for the maximum height and width of the usable display area in pixels (without scrolling).

The values calculated should represent the usable desktop area of a window maximized to fit the the screen.


Considerations
--- Multiple Monitors

For multiple monitors, the values calculated should represent the size of the usable display area on the monitor which is related to the task (i.e.:   the monitor which would display a window if such instructions were given).

--- Tiling Window Managers

For a tiling window manager, the values calculated should represent the maximum height and width of the display area of the maximum size a window can be created (without scrolling). This would typically be a full screen window (minus any areas occupied by desktop bars), unless the window manager has restrictions that prevents the creation of a full screen window, in which case the values represent the usable area of the desktop that occupies the maximum permissible window size (without scrolling).

Ada[edit]

Library: GTK
Library: GtkAda
with Gtk.Main;
with Glib;
with Gtk.Window; use Gtk.Window;
with Gtk.Enums; use Gtk.Enums;
with Ada.Text_IO; use Ada.Text_IO;
 
procedure Max_Size is
 
Win  : Gtk_Window;
Win_W, Win_H : Glib.Gint;
package Int_Io is new Integer_IO (Glib.Gint);
Hid : Gtk.Main.Quit_Handler_Id;
 
begin
Gtk.Main.Init;
Gtk_New (Win);
Initialize (Win, Window_Toplevel);
Maximize (Win);
Show (Win);
Get_Size (Win, Win_W, Win_H);
Put ("Maximum dimensions of window : W ");
Int_Io.Put (Win_W, Width => 4);
Put (" x H ");
Int_Io.Put (Win_H, Width => 4);
New_Line;
Hid := Gtk.Main.Quit_Add_Destroy (0, Win);
end Max_Size;

Output (on a 1280 x 800 screen with Windows XP):

Maximum dimensions of window : W 1280 x H  734

AutoHotkey[edit]

This is a modified example taken from the AutoHotkey documentation for the SysGet command. Also, the built in variables A_ScreenHeight and A_ScreenWidth contain the width and height of the primary monitor, in pixels.

SysGet, MonitorCount, MonitorCount
SysGet, MonitorPrimary, MonitorPrimary
MsgBox, Monitor Count:`t%MonitorCount%`nPrimary Monitor:`t%MonitorPrimary%
Loop, %MonitorCount%
{
SysGet, MonitorName, MonitorName, %A_Index%
SysGet, Monitor, Monitor, %A_Index%
SysGet, MonitorWorkArea, MonitorWorkArea, %A_Index%
MsgBox, % "Monitor:`t#" A_Index
. "`nName:`t" MonitorName
. "`nLeft:`t" MonitorLeft "(" MonitorWorkAreaLeft " work)"
. "`nTop:`t" MonitorTop " (" MonitorWorkAreaTop " work)"
. "`nRight:`t" MonitorRight " (" MonitorWorkAreaRight " work)"
. "`nBottom:`t" MonitorBottom " (" MonitorWorkAreaBottom " work)"
}

Output:

Monitor Count:    1
Primary Monitor:  1

Monitor:    #1
Name:       \\.\DISPLAY1
Left:       0(0 work)
Top:        0 (0 work)
Right:      1920 (1920 work)
Bottom:     1080 (1040 work)

Axe[edit]

Because Axe is currently (6/22/2015) only available on the TI-83/84 black and white calculators, the screen dimensions are fixed at 96 by 64 pixels.

BBC BASIC[edit]

      SPI_GETWORKAREA = 48
DIM rc{l%,t%,r%,b%}
SYS "SystemParametersInfo", SPI_GETWORKAREA, 0, rc{}, 0
PRINT "Maximum width = " ; rc.r% - rc.l%
PRINT "Maximum height = " ; rc.b% - rc.t%

Output:

Maximum width = 1367
Maximum height = 1021

Creative Basic[edit]

 
DEF Win:WINDOW
DEF Close:CHAR
 
DEF ScreenSizeX,ScreenSizeY:INT
DEF L,T,ClientWidth,ClientHeight:INT
 
GETSCREENSIZE(ScreenSizeX,ScreenSizeY)
 
WINDOW Win,0,0,ScreenSizeX,ScreenSizeY,@MINBOX|@MAXBOX|@SIZE|@MAXIMIZED,0,"Get Client Size",MainHandler
 
'Left and top are always zero for this function.
GETCLIENTSIZE(Win,L,T,ClientWidth,ClientHeight)
 
PRINT Win,"Maximum drawing area values: width is"+STR$(ClientWidth)+" and height is"+STR$(ClientHeight)+"."
 
WAITUNTIL Close=1
 
CLOSEWINDOW Win
 
END
 
SUB MainHandler
 
SELECT @CLASS
 
CASE @IDCLOSEWINDOW
 
Close=1
 
ENDSELECT
 
RETURN
 
Output: Maximum drawing area values: width is 1280 and height is 749.
 

EGL[edit]

To get the size of the window in a RuiHandler a JavaScript function is needed that is not natively supported by EGL. Therefore an external type is created to wrap the JavaScript function.

File 'Browser.js' in folder 'utils' in the WebContent folder of a rich UI project.

egl.defineClass(
	'utils', 'Browser',
{
	"getViewportWidth" : function () {
		return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
	},
	"getViewportHeight" : function(){
		return window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
	}
});

The external type to wrap the JavaScript functions.

ExternalType Browser type JavaScriptObject{
	relativePath = "utils",
	javaScriptName = "Browser"
}

	function getViewportWidth() returns (int);
	
	function getViewportHeight() returns (int);
	
end

Usage of the Browser external type in a RuiHandler.

 
browser Browser{};
bvh int = browser.getViewportHeight();
bvw int = browser.getViewportWidth();
SysLib.writeStdout("ViewportHeight: " + bvh);
SysLib.writeStdout("ViewportWidth: " + bvw);
 

Output

ViewportHeight: 860
ViewportWidth: 1680

FBSL[edit]

In the graphics mode, Windows does it all automatically and displays a form that fills the entire area not obscured by the taskbar on your primary monitor:

#INCLUDE <Include\Windows.inc>
ShowWindow(ME, SW_MAXIMIZE)
BEGIN EVENTS
END EVENTS

Alternatively, one can obtain the unobscured area's dimensions using the following console script:

#APPTYPE CONSOLE
#INCLUDE <Include\Windows.inc>
 
TYPE RECT
%Left
%Top
%Right
%Bottom
END TYPE
 
DIM rc AS RECT
SystemParametersInfo(SPI_GETWORKAREA, 0, @rc, 0)
PRINT "width = ", rc.Right - rc.Left, ", height = ", rc.Bottom - rc.Top
 
PAUSE

A typical output for a 1680x1050 primary monitor will be:

width = 1680, height = 1017

Press any key to continue...

FreeBASIC[edit]

' FB 1.05.0 Win64
 
' Using SystemParametersInfo function in Win32 API
Dim As Any Ptr library = DyLibLoad("user32")
Dim Shared SystemParametersInfo As Function (ByVal As ULong, ByVal As ULong, ByVal As Any Ptr, ByVal As ULong) As Long
SystemParametersInfo = DyLibSymbol(library, "SystemParametersInfoA")
 
Type Rect
As Long left, top, right, bottom
End Type
 
#Define SPI_GETWORKAREA &H30
Dim r As Rect
SystemParametersInfo(SPI_GETWORKAREA, 0, @r, 0)
DyLibFree(library)
Print "Maximum usable desktop area : W" ; r.right - r.left; " x H"; r.bottom - r.top; " pixels"
Print
Print "Press any key to quit"
Sleep

Output for my machine:

Output:
Maximum usable desktop area :  W 1366 x H 728 pixels

Gambas[edit]

Overview[edit]

In gambas, the trick to determining the maximum window size that will fit on the screen is to create a form that is maximized and then query its dimensions from within a Form_Resize() event. Note that the form can be invisible during this process, and typically we would use the main modal window (FMain in this example).

Creating the form[edit]

From with the project create a form (FMain) with the following properties set:

FMain.Maximized = True
FMain.Visible = False ' The form can be invisible

From within the projectview, rightclick the FMain form and select Edit class from the contextmenu. This will display a form class file (FMain.class) as follows:

PUBLIC SUB _new()
 
END
 
PUBLIC SUB Form_Open()
 
END

Adding the form resize event[edit]

We can now add a Form_Resize() event to the class file with the necessary code to obtain the screen dimensions as follows:

PUBLIC SUB Form_Resize()
PRINT "The maximum window size that can be used without scrolling is "; FMain.Width; " x "; FMain.Height
END

Gambas[edit]

Public Sub Form_Open()
 
Print Desktop.Width
Print Desktop.Height
 
End

Output:

1920
1055

Groovy[edit]

def window = java.awt.GraphicsEnvironment.localGraphicsEnvironment.maximumWindowBounds
 
println "width: $window.width, height: $window.height"

Haskell[edit]

import Graphics.UI.Gtk
import Control.Monad (when)
import Control.Monad.Trans (liftIO)
 
maximumWindowDimensions :: IO ()
maximumWindowDimensions = do
-- initialize the internal state of the GTK toolkit
initGUI
-- create a window
window <- windowNew
-- quit the application when the window is closed
on window objectDestroy mainQuit
-- query the size of the window when its dimensions change
on window configureEvent printSize
-- get the screen the window will be drawn upon
screen <- windowGetScreen window
-- get the size of the screen
x <- screenGetWidth screen
y <- screenGetHeight screen
-- print the dimensions of the screen
putStrLn ("The screen is " ++ show x ++ " pixels wide and " ++
show y ++ " pixels tall for an undecorated fullscreen window.")
-- maximize the window and show it. printSize will then be called
windowMaximize window
widgetShowAll window
-- run the main GTK loop.
-- close the window manually.
mainGUI
 
-- On my Xfce4 desktop, the configure_event is called three times when a
-- top level window is maximized. The first time, the window size
-- returned is the size prior to maximizing, and the last two times
-- it is the size after maximizing.
-- If the window is (un)maximized manually, the size returned is always
-- the size of the unmaximized window.
-- That means: either GTK or Xfce4 does not handle window maximization
-- correctly, or the GTK bindings for Haskell are buggy, or there is an
-- error in this program.
 
printSize :: EventM EConfigure Bool
printSize = do
-- get the window that has been resized
w <- eventWindow
-- is the window maximized?
s <- liftIO $ drawWindowGetState w
when (WindowStateMaximized `elem` s) $ do
-- get the size of the window that has been resized
(x, y) <- eventSize
-- print the dimensions out
liftIO $ putStrLn ("The inner window region is now " ++ show x ++
" pixels wide and " ++ show y ++ " pixels tall.")
return True

Icon and Unicon[edit]

Raise and query a hidden window.

link graphics
 
procedure main() # Window size
 
W := WOpen("canvas=hidden")
dh := WAttrib("displayheight")
dw := WAttrib("displaywidth")
WClose(W)
 
write("The display size is w=",dw,", h=",dh)
end


This example is in need of improvement:
Need to handle window borders which will vary from system to system and handle or comment on additional requirements.

IWBASIC[edit]

 
DEF Win:WINDOW
DEF Close:CHAR
 
DEF ScreenSizeX,ScreenSizeY:UINT
DEF L,T,ClientWidth,ClientHeight:INT
 
GETSCREENSIZE(ScreenSizeX,ScreenSizeY)
 
OPENWINDOW Win,0,0,ScreenSizeX,ScreenSizeY,@MAXBOX|@MINBOX|@SIZE|@MAXIMIZED,NULL,"Get client area",&MainHandler
 
'Left and top are always zero for this function.
GETCLIENTSIZE (Win,L,T,ClientWidth,ClientHeight)
 
PRINT Win,"Maximum drawing area values: width is"+STR$(ClientWidth)+" and height is"+STR$(ClientHeight)+"."
 
WAITUNTIL Close=1
 
CLOSEWINDOW WIN
 
END
 
SUB MainHandler
 
SELECT @MESSAGE
 
CASE @IDCLOSEWINDOW
 
Close=1
 
ENDSELECT
 
RETURN
ENDSUB
 
Output: Maximum drawing area values: width is 1280 and height is 749.
 

Java[edit]

import java.awt.*;
import javax.swing.JFrame;
 
public class Test extends JFrame {
 
public static void main(String[] args) {
new Test();
}
 
Test() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
 
Dimension screenSize = toolkit.getScreenSize();
System.out.println("Physical screen size: " + screenSize);
 
Insets insets = toolkit.getScreenInsets(getGraphicsConfiguration());
System.out.println("Insets: " + insets);
 
screenSize.width -= (insets.left + insets.right);
screenSize.height -= (insets.top + insets.bottom);
System.out.println("Max available: " + screenSize);
}
}

Output:

Physical screen size: java.awt.Dimension[width=1920,height=1080]
Insets: java.awt.Insets[top=0,left=0,bottom=30,right=0]
Max available: java.awt.Dimension[width=1920,height=1050]

Kotlin[edit]

Translation of: Java
// version 1.1
 
import java.awt.Toolkit
import javax.swing.JFrame
 
class Test : JFrame() {
init {
val r = Regex("""\[.*\]""")
val toolkit = Toolkit.getDefaultToolkit()
val screenSize = toolkit.screenSize
println("Physical screen size : ${formatOutput(screenSize, r)}")
val insets = toolkit.getScreenInsets(graphicsConfiguration)
println("Insets  : ${formatOutput(insets, r)}")
screenSize.width -= (insets.left + insets.right)
screenSize.height -= (insets.top + insets.bottom)
println("Max available  : ${formatOutput(screenSize, r)}")
}
 
private fun formatOutput(output: Any, r: Regex) = r.find(output.toString())!!.value.replace(",", ", ")
}
 
fun main(args: Array<String>) {
Test()
}

Sample output:

Output:
Physical screen size : [width=1366, height=768]
Insets               : [top=0, left=0, bottom=40, right=0]
Max available        : [width=1366, height=728]

Lingo[edit]

put _system.desktopRectList
-- [rect(0, 0, 1360, 768), rect(1360, 0, 2960, 1024)]

Mathematica / Wolfram Language[edit]

Example output on a 1280x1024 system.

[email protected]@SystemInformation["Devices"][[1, 2, 1, 1, 2]]
->{{1260, 951}}

Nim[edit]

Library: Gdk2
[edit]

Library: Gtk2
[edit]

import
gtk2, gdk2
 
nim_init()
var w = gdk2.screen_width()
var h = gdk2.screen_height()
echo("WxH=",w,"x",h)
Output:
WxH=1280x800

Library: IUP
[edit]

import
iup
 
# assumes you have the iup .dll or .so installed
 
discard iup.open(nil,nil)
 
var scrnFullSize = GetGlobal("FULLSIZE")
var scrnSize = GetGlobal("SCREENSIZE")
var scrnMInfo = GetGlobal("MONITORSINFO")
var scrnVScreen = GetGlobal("VIRTUALSCREEN")
 
var dlg = Dialog(nil)
SetAttribute(dlg, "SIZE", "FULL")
var scrnXSize = GetAttribute(dlg,"MAXSIZE")
 
echo scrnFullSize, "\n", scrnSize, "\n", scrnMInfo, "\n", scrnVScreen, "\n", scrnXSize
 
discard iup.Alarm("Screen client size", scrnFullSize ,"Ok",nil, nil)
 
#discard iup.mainloop()
iup.close()
Output:
1280x800
1280x800
0 0 1280 800

0 0 1280 800
65535x65535

PARI/GP[edit]

plothsizes()[1..2]

Perl[edit]

Library: Perl/Tk
[edit]

 
use strict;
use warnings;
use Tk;
 
sub get_size {
my $mw = MainWindow->new();
return ($mw->maxsize);
}
 

get_size returns (1425,870) here.

Phix[edit]

Translation of: Nim
Library: pGUI
include pGUI.e
 
IupOpen()
 
string scrnFullSize = IupGetGlobal("FULLSIZE")
string scrnSize = IupGetGlobal("SCREENSIZE")
string scrnMInfo = IupGetGlobal("MONITORSINFO")
string scrnVScreen = IupGetGlobal("VIRTUALSCREEN")
 
Ihandle dlg = IupDialog(NULL,"SIZE=FULL")
string scrnXSize = IupGetAttribute(dlg,"MAXSIZE")
 
?{scrnFullSize, scrnSize, scrnMInfo, scrnVScreen, scrnXSize}
 
IupClose()
Output:
{"1920x1080","1920x1080","0 0 1920 1080\n","0 0 1920 1080","65535x65535"}

You could instead use atom {x,y} = IupGetIntInt(NULL,"FULLSIZE"|"SCREENSIZE"|"MAXSIZE") to get numbers instead of strings.

PicoLisp[edit]

The following works on ErsatzLisp, the Java version of PicoLisp.

(let Frame (java "javax.swing.JFrame" T "Window")
(java Frame 'setExtendedState
(java (public "javax.swing.JFrame" 'MAXIMIZED_BOTH)) )
(java Frame 'setVisible T)
(wait 200)
(let Size (java (java Frame 'getContentPane) 'getSize)
(prinl "Width: " (java (public Size 'width)))
(prinl "Height: " (java (public Size 'height))) )
(java Frame 'dispose) )

Output (on a 1024x768 screen):

Width: 1010
Height: 735

PureBasic[edit]

If OpenWindow(0, 0, 0, 5, 5, "", #PB_Window_Maximize + #PB_Window_Invisible)
maxX = WindowWidth(0)
maxY = WindowHeight(0)
CloseWindow(0)
MessageRequester("Result", "Maximum Window Width: " + Str(maxX) + ", Maximum Window Height: " + Str(maxY))
EndIf

Sample output for a screen area 1600 x 1200:

Maximum Window Width: 1600, Maximum Window Height: 1181

Python[edit]

 
#!/usr/bin/env python3
 
import tkinter as tk # import the module.
 
root = tk.Tk() # Create an instance of the class.
root.state('zoomed') # Maximized the window.
root.update_idletasks() # Update the display.
tk.Label(root, text=(str(root.winfo_width())+ " x " +str(root.winfo_height())),
font=("Helvetica", 25)).pack() # add a label and set the size to text.
root.mainloop()
 

Sample output for 1366 x 768 screen:

1366 x 706

Racket[edit]

 
#lang racket/gui
(define-values [W H]
(let ([f (new frame% [label "test"])])
(begin0 (send* f (maximize #t) (show #t) (get-client-size))
(send f show #f))))
(printf "~ax~a\n" W H)
 

Ring[edit]

 
load "guilib.ring"
new qApp {
win1 = new qWidget() {
new qPushButton(win1) {
resize(200,200)
settext("Info")
setclickevent(' win1{ setwindowtitle("Width: " + width() + " Height : " + height() ) }')
}
showMaximized()}
exec()
}
 

Output:

CalmoSoftWindowSize.jpg

Run BASIC[edit]

Run Basic uses javaScript to return the width of the browser window. IE browser uses different functions than everyone else. So you write code for the world, and also for IE

 
html "<INPUT TYPE='HIDDEN' id='winHigh' name='winHigh' VALUE='";winHigh;"'></input>"
html "<INPUT TYPE='HIDDEN' id='winWide' name='winWide' VALUE='";winWide;"'></input>"
 
html "<script>
<!--
 
function winSize()
{
var myWide = 0, myHigh = 0;
if( typeof( window.innerWidth ) == 'number' ) {
//Non-IE
myWide = window.innerWidth;
myHigh = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode'
myWide = document.documentElement.clientWidth;
myHigh = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
//IE 4 compatible
myWide = document.body.clientWidth;
myHigh = document.body.clientHeight;
}
// window.alert( 'Width = ' + myWide + ' Height = ' + myHigh );
document.getElementById('winHigh').value = myHigh;
document.getElementById('winWide').value = myWide;
}
 
window.onresize = function()
{
var x = winSize();
}
var x = winSize();
//--></script>
"

Sidef[edit]

Using the Tk library:

require('Tk')
 
func max_window_size() -> (Number, Number) {
%s'MainWindow'.new.maxsize;
}
 
var (width, height) = max_window_size();
say (width, 'x', height);
Output:
1905x1050

Tcl[edit]

Library: Tk
package require Tk
proc maxSize {} {
# Need a dummy window; max window can be changed by scripts
set top .__defaultMaxSize__
if {![winfo exists $top]} {
toplevel $top
wm withdraw $top
}
# Default max size of window is value we want
return [wm maxsize $top]
}

On this system, that returns 1440 836. Further discussion of related matters, including platform limitations, is on the Tcler's Wiki.

Visual Basic[edit]

Method 1[edit]

The first method involves querying the screen dimensions and then subtracting pixels used by the frame and desktop bars:

TYPE syswindowstru
screenheight AS INTEGER
screenwidth AS INTEGER
maxheight AS INTEGER
maxwidth AS INTEGER
END TYPE
 
DIM syswindow AS syswindowstru
 
' Determine the height and width of the screen

syswindow.screenwidth = Screen.Width / Screen.TwipsPerPixelX
syswindow.screenheight=Screen.Height / Screen.TwipsPerPixelY
 
' Make adjustments for window decorations and menubars

Method 2[edit]

The alternative method is to create a form that is maximized and then query its dimensions (similar to the method used in gambas).