Get Desktop Metrics In Multi-Display Setup

Share your advanced PureBasic knowledge/code with the community.
User avatar
TI-994A
Addict
Addict
Posts: 2512
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Get Desktop Metrics In Multi-Display Setup

Post by TI-994A »

This cross-platform (Windows, MacOS, Linux) routine determines:
1. the main desktop
2. the mouse position
3. the desktop that the mouse is hovering on, and
4. the desktop that the app is positioned in (based on app window x/y position)

Code: Select all

;===========================================================
;
;   getDesktopInfo() returns various metrics
;   regarding the mouse, app, and desktops
;
;   tested & working with PureBasic v5.73 LTS (x64) on:
;   - MacOS Catalina 10.15.5
;   - Linux Ubuntu 20.04.2 LTS
;   - Windows 8.1 Professional
;
;   by TI-994A - free to use, improve, share...
;
;   5th December 2016
;
;   Updated: 23rd March 2021
;
;===========================================================

Structure xPoint
  x.i
  y.i
EndStructure

Structure desktop
  app.xPoint
  mouse.xPoint
  appDesktop.i
  mouseDesktop.i
  mainDesktop.i
  appWin.i
  desktop.i
EndStructure

;just drop this routine into any application (requires the desktop structure above)
;and simply poll the relevant elements to determine the required desktop metrics
;
Procedure getDesktopInfo(*ds.desktop)
  Protected desktops = ExamineDesktops()
  Protected i, dx, dy, dw, dh
 
  With *ds
   
    \mouse\x = DesktopMouseX()
    \mouse\y = DesktopMouseY()
    \app\x = WindowX(\appWin)
    \app\y = WindowY(\appWin)
   
    For i = 0 To desktops -1
     
      dx = DesktopX(i)
      dy = DesktopY(i)
      dw = DesktopWidth(i)
      dh = DesktopHeight(i)
     
      If \app\x >= dx And \app\x <= dx + dw And
         \app\y >= dy And \app\y <= dy + dh
        \appDesktop = i
      EndIf     
     
      If \mouse\x >= dx And \mouse\x <= dx + dw And
         \mouse\y >= dy And \mouse\y <= dy + dh
        \mouseDesktop = i       
        If dx = 0 And dy = 0
          \mainDesktop = i
        EndIf             
        Break
      EndIf
     
    Next i
   
  EndWith
 
EndProcedure

;demo
;
desktop.desktop

LoadFont(0, "Arial", 16)
SetGadgetFont(#PB_Default, FontID(0))

wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
mainWin = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore,
                     500, 300, "Active Desktops", wFlags)
desktopInfo = TextGadget(#PB_Any, 50, 50, 400, 50, "")
mousePos = TextGadget(#PB_Any, 50, 120, 400, 50, "")
appPos = TextGadget(#PB_Any, 50, 190, 400, 50, "")
AddWindowTimer(mainWin, 0, 100)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      appQuit = #True
     
    Default
      desktop\appWin = mainWin
      getDesktopInfo(@desktop)
      With desktop
        SetGadgetText(desktopInfo, "Desktop " +
                                   Str(\mainDesktop) + " is the main desktop")
        SetGadgetText(mousePos, "The mouse is at " + Str(\mouse\x) + ", " +
                                Str(\mouse\y) + " on desktop " + Str(\mouseDesktop))
        SetGadgetText(appPos, "The app is on desktop " + Str(\appDesktop))
      EndWith
  EndSelect
Until appQuit
Suggestions, improvements, and feedback are welcome! :wink:
Last edited by TI-994A on Tue Mar 23, 2021 11:03 am, edited 1 time in total.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
BarryG
Addict
Addict
Posts: 3293
Joined: Thu Apr 18, 2019 8:17 am

Re: Get Desktop Metrics In Multi-Display Setup

Post by BarryG »

Thanks TI-994A, I had a need for this today.
User avatar
TI-994A
Addict
Addict
Posts: 2512
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Get Desktop Metrics In Multi-Display Setup

Post by TI-994A »

BarryG wrote:Thanks TI-994A, I had a need for this today.
Thanks for saying so, Barry. Glad it was helpful.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Get Desktop Metrics In Multi-Display Setup

Post by davido »

@TI-994A,

Thank you for sharing.

It appears to work perfectly on Bigsur running on the new m1 system.





Model Name: MacBook Pro
Model Identifier: MacBookPro17,1
Chip: Apple M1
Total Number of Cores: 8 (4 performance and 4 efficiency)
Memory: 8 GB
System Version: macOS 11.2.2 (20D80)
Kernel Version: Darwin 20.3.0
DE AA EB
User avatar
skywalk
Addict
Addict
Posts: 3972
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Get Desktop Metrics In Multi-Display Setup

Post by skywalk »

Wow, very concise. Thanks TI-994A 8)
I will tinker with this to align with the Windows 10 assignments for Displays.
My stacked 3 monitor case:

Code: Select all

Windows10               ThisSnippet    
Display3 - 3rd          1
Display2 - 2nd          2
Display1 - Main         0
DesktopName,Width,Height,ResolutionX,ResolutionY,X,Y
\\.\DISPLAY1,1920,1080,1,1,0,0
\\.\DISPLAY4,1920,1080,1,1,-13,-2160
\\.\DISPLAY5,1920,1080,1,1,-13,-1080
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: Get Desktop Metrics In Multi-Display Setup

Post by Josh »

Thanks TI. I just tested it on Win7. Looks good, but one little thing strikes me as a bit odd:

When I move the window from one screen to the other, the display "The app is on desktop 1" changes to "The app is on desktop 0" exactly when the window is completely on desktop 0. This seems correct and logical to me.

But when I move the window the other way the display "The app is on desktop 0" changes to "The app is on desktop 1" already when the window is only a little bit on desktop 1 AND then I move the mouse (only the mouse) also to deskop 1.

What you might need to know. In my case the desktop 0 is on the right side, so the x-coordinates of desktop 1 are negative.
sorry for my bad english
User avatar
skywalk
Addict
Addict
Posts: 3972
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Get Desktop Metrics In Multi-Display Setup

Post by skywalk »

Yes, the assignment logic has to go through more rigor.
The main desktop is assumed to have a 0,0 coordinate and any additional desktops are relative to that.
In my case, stacked 3 monitors with different DPI so they have ±x, ±y coordinates.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
TI-994A
Addict
Addict
Posts: 2512
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Get Desktop Metrics In Multi-Display Setup

Post by TI-994A »

@davido, @skywalk, @Josh, thank you for your kind words and valuable feedback.

The code has been slightly modified to better poll the position of the app window; and it has also been tested on Linux (and MacOS Big Sur on M1, thanks to @davido).

The position of the app window is determined purely by its top-left x,y coordinates, although many other factors could be considered to improve this.

However, on MaOS, with the Separate Space Displays option activated, app windows do not span the extended screens, and are visible only on the display where the windows are dropped, regardless of their top-left locations. This would require some API to determine.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
Post Reply