I know how to detect the right window size (minus the taskbar) in Windows, thanks to this code by @bplus,
however if the program detects that the user is not in Windows, what code can we use to find the optimal window size?
If possible I would include code to detect OS and set the screen size dymaincally, so my prog can be cross-platform.
Update: I asked Gemini about this and it spit out some code, can someone running QB64PE on Mac or Linux try this out?
Prompt:
Write a QB64PE 4.1.0 program to detect the operating system, and if it is not Windows, detect the correct window size minus the taskbar and title bar?
To do it in Windows we can use the code at https://qb64phoenix.com/forum/showthread...8#pid22318
However how do you do it for Mac and Linux?
Answer:
This is an excellent question that gets into the cross-platform capabilities of QB64PE. The Windows method uses the Win32 API, so for Mac and Linux, we need to call their respective native C libraries, just as the Windows example does.
I tried correcting some errors in the code, but since I don't have certain Mac or Linux librarys on my machine, the IDE is showing errors for those missing files:
however if the program detects that the user is not in Windows, what code can we use to find the optimal window size?
If possible I would include code to detect OS and set the screen size dymaincally, so my prog can be cross-platform.
Update: I asked Gemini about this and it spit out some code, can someone running QB64PE on Mac or Linux try this out?
Prompt:
Write a QB64PE 4.1.0 program to detect the operating system, and if it is not Windows, detect the correct window size minus the taskbar and title bar?
To do it in Windows we can use the code at https://qb64phoenix.com/forum/showthread...8#pid22318
However how do you do it for Mac and Linux?
Answer:
This is an excellent question that gets into the cross-platform capabilities of QB64PE. The Windows method uses the Win32 API, so for Mac and Linux, we need to call their respective native C libraries, just as the Windows example does.
- On macOS, we can use the CoreGraphics framework and call CGDisplayAvailableRect.
- On Linux, we use the libX11 library to query the _NET_WORKAREA property from the root window, which is the standard way to get the usable desktop area (excluding panels, docks, etc.) on modern X11 desktops.
Code: (Select All)
' QB64PE 4.1.0 Program to Detect OS and Find Usable Screen "Work Area"
' This program demonstrates using DECLARE DYNAMIC LIBRARY to call
' native OS functions on Windows, Linux, and macOS.
' Suppress errors if a library isn't found (e.g., trying to load libX11 on Windows)
'$NOPREFIX
OPTION _EXPLICIT
DIM os AS STRING
os = _ENVIRON$("OS")
PRINT "QB64PE Operating System Detection"
PRINT "================================="
PRINT "Detected OS: "; os
PRINT
DIM workX AS _INTEGER64, workY AS _INTEGER64
DIM workW AS _INTEGER64, workH AS _INTEGER64
SELECT CASE os
CASE "WINDOWS"
' --- Windows Method (using SystemParametersInfoA) ---
PRINT "Using Windows API (user32.dll)..."
' Define the RECT TYPE required by the Windows API
TYPE RECT
Left AS LONG ' QB64 32-bit LONG
Top AS LONG
Right AS LONG
Bottom AS LONG
END TYPE
DIM workArea AS RECT
' Declare the function from user32.dll
DECLARE DYNAMIC LIBRARY "user32"
FUNCTION SystemParametersInfoA (BYVAL uiAction AS LONG, BYVAL uiParam AS LONG, lpvParam AS RECT, BYVAL fWinIni AS LONG) AS LONG
END DECLARE
CONST SPI_GETWORKAREA = 48 ' Action to get the work area
IF SystemParametersInfoA(SPI_GETWORKAREA, 0, workArea, 0) THEN
' Successful call
workX = workArea.Left
workY = workArea.Top
workW = workArea.Right - workArea.Left
workH = workArea.Bottom - workArea.Top
ELSE
' Fallback on failure
PRINT "SystemParametersInfoA failed. Using full resolution."
workX = 0
workY = 0
workW = _WIDTH
workH = _HEIGHT
END IF
CASE "MACOSX"
' --- macOS Method (using CoreGraphics Framework) ---
PRINT "Using macOS API (CoreGraphics.framework)..."
' Define CoreGraphics TYPEs
' CGFloat is a DOUBLE on 64-bit systems
TYPE CGPoint
x AS DOUBLE
y AS DOUBLE
END TYPE
TYPE CGSize
width AS DOUBLE
height AS DOUBLE
END TYPE
TYPE CGRect
origin AS CGPoint
size AS CGSize
END TYPE
DIM displayRect AS CGRect
' CGDirectDisplayID is a 32-bit unsigned int, but _UNSIGNED LONG (64-bit)
' as parameter type and LONG (64-bit) for return works for passing the ID.
DIM mainDisplayID AS _UNSIGNED LONG
' Declare functions from the CoreGraphics framework
' Note: On Mac, we link to the "framework" itself
DECLARE DYNAMIC LIBRARY "CoreGraphics"
FUNCTION CGMainDisplayID () AS _UNSIGNED LONG
FUNCTION CGDisplayAvailableRect (BYVAL display AS _UNSIGNED LONG) AS CGRect
END DECLARE
mainDisplayID = CGMainDisplayID()
displayRect = CGDisplayAvailableRect(mainDisplayID)
' CGRect origin (0,0) is top-left, matching QB64's coordinate system.
workX = displayRect.origin.x
workY = displayRect.origin.y
workW = displayRect.size.width
workH = displayRect.size.height
CASE "LINUX"
' --- Linux Method (using libX11) ---
PRINT "Using Linux API (libX11.so)..."
' We need _OFFSET for C pointers
DIM display AS _OFFSET
DIM rootWindow AS _OFFSET ' This is a Window ID, but passed as pointer/long
DIM workAreaAtom AS _OFFSET ' This is an Atom ID
DIM result AS LONG
' Variables for XGetWindowProperty
DIM actual_type AS _OFFSET, actual_format AS LONG
DIM nitems AS _OFFSET, bytes_after AS _OFFSET
DIM prop_data_ptr AS _OFFSET ' This will be a pointer to the result
' libX11 functions
DECLARE DYNAMIC LIBRARY "libX11"
FUNCTION XOpenDisplay (BYVAL display_name AS _OFFSET) AS _OFFSET ' Returns Display*
FUNCTION DefaultRootWindow (BYVAL display AS _OFFSET) AS _OFFSET ' Returns Window
FUNCTION XInternAtom (BYVAL display AS _OFFSET, BYVAL atom_name AS STRING, BYVAL only_if_exists AS LONG) AS _OFFSET ' Returns Atom
FUNCTION XGetWindowProperty (BYVAL display AS _OFFSET, BYVAL w AS _OFFSET, BYVAL property AS _OFFSET, BYVAL long_offset AS _OFFSET, BYVAL long_length AS _OFFSET, BYVAL delete AS LONG, BYVAL req_type AS _OFFSET, actual_type_return AS _OFFSET, actual_format_return AS LONG, nitems_return AS _OFFSET, bytes_after_return AS _OFFSET, prop_return AS _OFFSET) AS LONG ' Returns int
FUNCTION XFree (BYVAL data AS _OFFSET) AS LONG ' Returns int
FUNCTION XCloseDisplay (BYVAL display AS _OFFSET) AS LONG ' Returns int
END DECLARE
display = XOpenDisplay(0) ' 0 is NULL, means default display
IF display = 0 THEN
PRINT "Could not open X Display. Using full resolution."
workX = 0: workY = 0: workW = _WIDTH: workH = _HEIGHT
ELSE
rootWindow = DefaultRootWindow(display)
workAreaAtom = XInternAtom(display, "_NET_WORKAREA", 0) ' 0 = False
' Pointers to receive return values for XGetWindowProperty
DIM pActualType AS _MEM: pActualType = _MEMNEW(8)
DIM pActualFormat AS _MEM: pActualFormat = _MEMNEW(8)
DIM pNItems AS _MEM: pNItems = _MEMNEW(8)
DIM pBytesAfter AS _MEM: pBytesAfter = _MEMNEW(8)
DIM pPropData AS _MEM: pPropData = _MEMNEW(8)
result = XGetWindowProperty(display, rootWindow, workAreaAtom, 0, 4, 0, 0, pActualType.OFFSET, pActualFormat.OFFSET, pNItems.OFFSET, pBytesAfter.OFFSET, pPropData.OFFSET)
nitems = _MEMGET(pNItems, 0, _OFFSET)
actual_format = _MEMGET(pActualFormat, 0, LONG)
prop_data_ptr = _MEMGET(pPropData, 0, _OFFSET)
' _NET_WORKAREA returns 4 32-bit cardinals (x, y, w, h)
' We check for Success (0), 4 items, and 32-bit format
IF result = 0 AND nitems = 4 AND actual_format = 32 THEN
' Read the 4 32-bit integers from the pointer
' We use _UNSIGNED LONG which is a 32-bit type in QB64PE
DIM workAreaMem AS _MEM
workAreaMem = _MEM(prop_data_ptr, 16) ' Map 16 bytes (4 * 4)
workX = _MEMGET(workAreaMem, 0, _UNSIGNED LONG)
workY = _MEMGET(workAreaMem, 4, _UNSIGNED LONG)
workW = _MEMGET(workAreaMem, 8, _UNSIGNED LONG)
workH = _MEMGET(workAreaMem, 12, _UNSIGNED LONG)
_MEMFREE workAreaMem
XFree prop_data_ptr ' Free the memory X11 allocated
ELSE
' Fallback on failure (e.g., non-EWMH compliant window manager)
PRINT "Could not get _NET_WORKAREA. Using full resolution."
workX = 0: workY = 0: workW = _WIDTH: workH = _HEIGHT
END IF
' Free memory used for pointers
_MEMFREE pActualType
_MEMFREE pActualFormat
_MEMFREE pNItems
_MEMFREE pBytesAfter
_MEMFREE pPropData
XCloseDisplay display ' Close connection to X server
END IF
CASE ELSE
' --- Fallback for other OS (e.g., FreeBSD) ---
PRINT "Unknown OS. Using full screen resolution as fallback."
workX = 0
workY = 0
workW = _WIDTH
workH = _HEIGHT
END SELECT
' --- Display Results ---
PRINT
PRINT "Usable Work Area Results"
PRINT "--------------------------"
PRINT "Top-Left X: "; workX
PRINT "Top-Left Y: "; workY
PRINT "Width: "; workW
PRINT "Height: "; workH
PRINT
PRINT "Full screen resolution for comparison:"
PRINT "Width: "; _WIDTH
PRINT "Height:"; _HEIGHT
ENDI tried correcting some errors in the code, but since I don't have certain Mac or Linux librarys on my machine, the IDE is showing errors for those missing files:
Code: (Select All)
' QB64PE 4.1.0 Program to Detect OS and Find Usable Screen "Work Area"
' This program demonstrates using DECLARE DYNAMIC LIBRARY to call
' native OS functions on Windows, Linux, and macOS.
' Suppress errors if a library isn't found (e.g., trying to load libX11 on Windows)
'$NOPREFIX
Option _Explicit
Dim os As String
'os = _ENVIRON$("OS")
os = _OS$
Print "QB64PE Operating System Detection"
Print "================================="
Print "Detected OS: "; os
Print
Dim workX As _Integer64, workY As _Integer64
Dim workW As _Integer64, workH As _Integer64
Select Case os
Case "WINDOWS"
' --- Windows Method (using SystemParametersInfoA) ---
Print "Using Windows API (user32.dll)..."
' Define the RECT TYPE required by the Windows API
Type RECT
Left As Long ' QB64 32-bit LONG
Top As Long
Right As Long
Bottom As Long
End Type
Dim workArea As RECT
' Declare the function from user32.dll
Declare Dynamic Library "user32"
Function SystemParametersInfoA& (ByVal uiAction As Long, ByVal uiParam As Long, lpvParam As RECT, ByVal fWinIni As Long)
End Declare
Const SPI_GETWORKAREA = 48 ' Action to get the work area
If SystemParametersInfoA(SPI_GETWORKAREA, 0, workArea, 0) Then
' Successful call
workX = workArea.Left
workY = workArea.Top
workW = workArea.Right - workArea.Left
workH = workArea.Bottom - workArea.Top
Else
' Fallback on failure
Print "SystemParametersInfoA failed. Using full resolution."
workX = 0
workY = 0
workW = _Width
workH = _Height
End If
Case "MACOSX"
' --- macOS Method (using CoreGraphics Framework) ---
Print "Using macOS API (CoreGraphics.framework)..."
' Define CoreGraphics TYPEs
' CGFloat is a DOUBLE on 64-bit systems
Type CGPoint
x As Double
y As Double
End Type
Type CGSize
width As Double
height As Double
End Type
Type CGRect
origin As CGPoint
size As CGSize
End Type
Dim displayRect As CGRect
' CGDirectDisplayID is a 32-bit unsigned int, but _UNSIGNED LONG (64-bit)
' as parameter type and LONG (64-bit) for return works for passing the ID.
Dim mainDisplayID As _Unsigned Long
' Declare functions from the CoreGraphics framework
' Note: On Mac, we link to the "framework" itself
' ****************************************************************************************************************************************************************
' IDE GIVES DYNAMIC LIBRARY not found error:
' ****************************************************************************************************************************************************************
DECLARE DYNAMIC LIBRARY "CoreGraphics"
FUNCTION CGMainDisplayID~& ()
' ****************************************************************************************************************************************************************
' HOW DO YOU DECLARE A UDT RETURN TYPE LIKE CGRect? (TRIED CHANGING TO _OFFSET TO GET PAST THE ERROR)
FUNCTION CGDisplayAvailableRect%& (BYVAL display AS _UNSIGNED LONG) 'AS CGRect
END DECLARE
mainDisplayID = CGMainDisplayID()
displayRect = CGDisplayAvailableRect(mainDisplayID)
' CGRect origin (0,0) is top-left, matching QB64's coordinate system.
workX = displayRect.origin.x
workY = displayRect.origin.y
workW = displayRect.size.width
workH = displayRect.size.height
Case "LINUX"
' --- Linux Method (using libX11) ---
Print "Using Linux API (libX11.so)..."
' We need _OFFSET for C pointers
Dim display As _Offset
Dim rootWindow As _Offset ' This is a Window ID, but passed as pointer/long
Dim workAreaAtom As _Offset ' This is an Atom ID
Dim result As Long
' Variables for XGetWindowProperty
Dim actual_type As _Offset, actual_format As Long
Dim nitems As _Offset, bytes_after As _Offset
Dim prop_data_ptr As _Offset ' This will be a pointer to the result
' libX11 functions
' ****************************************************************************************************************************************************************
' IDE GIVES DYNAMIC LIBRARY not found error:
' ****************************************************************************************************************************************************************
DECLARE DYNAMIC LIBRARY "libX11"
FUNCTION XOpenDisplay%& (BYVAL display_name AS _OFFSET) ' Returns Display*
FUNCTION DefaultRootWindow%& (BYVAL display AS _OFFSET) ' Returns Window
FUNCTION XInternAtom%& (BYVAL display AS _OFFSET, BYVAL atom_name AS STRING, BYVAL only_if_exists AS LONG) ' Returns Atom
FUNCTION XGetWindowProperty& (BYVAL display AS _OFFSET, BYVAL w AS _OFFSET, BYVAL property AS _OFFSET, BYVAL long_offset AS _OFFSET, BYVAL long_length AS _OFFSET, BYVAL delete AS LONG, BYVAL req_type AS _OFFSET, actual_type_return AS _OFFSET, actual_format_return AS LONG, nitems_return AS _OFFSET, bytes_after_return AS _OFFSET, prop_return AS _OFFSET) ' Returns int
FUNCTION XFree& (BYVAL data1 AS _OFFSET) ' Returns int
FUNCTION XCloseDisplay& (BYVAL display AS _OFFSET) ' Returns int
END DECLARE
display = XOpenDisplay(0) ' 0 is NULL, means default display
IF display = 0 THEN
PRINT "Could not open X Display. Using full resolution."
workX = 0: workY = 0: workW = _WIDTH: workH = _HEIGHT
ELSE
rootWindow = DefaultRootWindow(display)
workAreaAtom = XInternAtom(display, "_NET_WORKAREA", 0) ' 0 = False
' Pointers to receive return values for XGetWindowProperty
DIM pActualType AS _MEM: pActualType = _MEMNEW(8)
DIM pActualFormat AS _MEM: pActualFormat = _MEMNEW(8)
DIM pNItems AS _MEM: pNItems = _MEMNEW(8)
DIM pBytesAfter AS _MEM: pBytesAfter = _MEMNEW(8)
DIM pPropData AS _MEM: pPropData = _MEMNEW(8)
result = XGetWindowProperty(display, rootWindow, workAreaAtom, 0, 4, 0, 0, pActualType.OFFSET, pActualFormat.OFFSET, pNItems.OFFSET, pBytesAfter.OFFSET, pPropData.OFFSET)
nitems = _MEMGET(pNItems, 0, _OFFSET)
actual_format = _MEMGET(pActualFormat, 0, LONG)
prop_data_ptr = _MEMGET(pPropData, 0, _OFFSET)
' _NET_WORKAREA returns 4 32-bit cardinals (x, y, w, h)
' We check for Success (0), 4 items, and 32-bit format
IF result = 0 AND nitems = 4 AND actual_format = 32 THEN
' Read the 4 32-bit integers from the pointer
' We use _UNSIGNED LONG which is a 32-bit type in QB64PE
DIM workAreaMem AS _MEM
workAreaMem = _MEM(prop_data_ptr, 16) ' Map 16 bytes (4 * 4)
workX = _MEMGET(workAreaMem, 0, _UNSIGNED LONG)
workY = _MEMGET(workAreaMem, 4, _UNSIGNED LONG)
workW = _MEMGET(workAreaMem, 8, _UNSIGNED LONG)
workH = _MEMGET(workAreaMem, 12, _UNSIGNED LONG)
_MEMFREE workAreaMem
XFree prop_data_ptr ' Free the memory X11 allocated
ELSE
' Fallback on failure (e.g., non-EWMH compliant window manager)
PRINT "Could not get _NET_WORKAREA. Using full resolution."
workX = 0: workY = 0: workW = _WIDTH: workH = _HEIGHT
END IF
' Free memory used for pointers
_MEMFREE pActualType
_MEMFREE pActualFormat
_MEMFREE pNItems
_MEMFREE pBytesAfter
_MEMFREE pPropData
XCloseDisplay display ' Close connection to X server
END IF
CASE ELSE
' --- Fallback for other OS (e.g., FreeBSD) ---
PRINT "Unknown OS. Using full screen resolution as fallback."
workX = 0
workY = 0
workW = _WIDTH
workH = _HEIGHT
END SELECT
' --- Display Results ---
PRINT
PRINT "Usable Work Area Results"
PRINT "--------------------------"
PRINT "Top-Left X: "; workX
PRINT "Top-Left Y: "; workY
PRINT "Width: "; workW
PRINT "Height: "; workH
PRINT
PRINT "Full screen resolution for comparison:"
PRINT "Width: "; _WIDTH
PRINT "Height:"; _HEIGHT
END

![[Image: 2025-11-02-23-03.png]](https://i.ibb.co/RpMY98Nb/2025-11-02-23-03.png)

![[Image: detect-max-screen-resolution-bas-1.png]](https://i.ibb.co/KcKYdfqx/detect-max-screen-resolution-bas-1.png)
![[Image: detect-max-screen-resolution-bas-2.png]](https://i.ibb.co/Mx547FDd/detect-max-screen-resolution-bas-2.png)