How to list windows, and their information, under Microsoft windows, Linux and macOS

 

A window is just a place, where an application can do its drawing, like drawing a button, text or other stuff.

Table of Contents

For Linux

On Linux or UNIX like systems, there is a tool called xwininfo, which can be used to list all the windows, on a system. Hence you would be able to get, the windows IDs, and names.

Additionally, xwininfo can be used, to get the attributes of a specific window, such as, where it is located , its width , height.

Having gotten a window id, you can also query a window for its properties, using xprop . A window property, is a way to exchange information, between windows.

$ xwininfo -root -tree
# List all windows, starting 
# from the root of the screen, in
# a tree manner. 
# The window id is displayed, 
# so for example, for the 
# Calculator window, its id is 
# 0x800011.
# In addition to the window id,
# its name is displayed, so for 
# the window which has an id of 
# 0x800011 ,its name is calculator. 
xwininfo: Window id: 0xac (the root window) (has no name)

  Root window id: 0xac (the root window) (has no name)
  Parent window id: 0x0 (none)
     2 children:
     0x800011 "Calculator": ("xcalc" "XCalc")  226x394+59+82  +59+82
        1 child:
        0x800012 (has no name): ()  226x394+0+0  +59+82
           56 children:
           0x80004b (has no name): ()  216x46+4+2  +63+84
              1 child:
              0x80004c (has no name): ()  204x38+6+2  +70+87
                 10 children:
                 0x800056 (has no name): ()  10x15+4+2  +75+90
                 0x800055 (has no name): ()  186x17+18+2  +89+90
                 ...
                 0x80004e (has no name): ()  26x15+146+21  +217+109
                 0x80004d (has no name): ()  26x15+146+21  +217+109
           0x80004a (has no name): ()  40x26+4+62  +63+144
           0x800049 (has no name): ()  40x26+48+62  +107+144
           0x800048 (has no name): ()  40x26+92+62  +151+144
           ... 
           0x800015 (has no name): ()  40x26+136+362  +195+444
           0x800014 (has no name): ()  40x26+180+362  +239+444
     0x600000 "xwinclip": ()  500x500+1+1  +1+1



$ xwininfo -name Calculator
# List the attributes, of the 
# Calculator window, as in its
# width, height, x and 
# y positions .. 
xwininfo: Window id: 0x800011 "Calculator"

  Absolute upper-left X:  59
  Absolute upper-left Y:  82
  Relative upper-left X:  59
  Relative upper-left Y:  82
  Width: 226
  Height: 394
  Depth: 24
  Visual: 0x21
  Visual Class: TrueColor
  Border width: 0
  Class: InputOutput
  Colormap: 0x20 (installed)
  Bit Gravity State: NorthWestGravity
  Window Gravity State: NorthWestGravity
  Backing Store State: NotUseful
  Save Under State: no
  Map State: IsViewable
  Override Redirect State: no
  Corners:  +59+82  -1081+82  -1081-292  +59-292
  -geometry 226x394+59+82

$ xprop -name Calculator
# List the properties, of the 
# window, named Calculator. A
# property is used to exchange
# information, for example, 
# between the window, and the
# window manager. 
WM_STATE(WM_STATE):
                window state: Normal
                icon window: 0x0
WM_PROTOCOLS(ATOM): protocols  WM_DELETE_WINDOW
WM_CLIENT_LEADER(WINDOW): window id # 0x800011
WM_LOCALE_NAME(STRING) = "en_US.UTF-8"
WM_CLASS(STRING) = "xcalc", "XCalc"
WM_HINTS(WM_HINTS):
                Client accepts input or input focus: True
                Initial state is Normal State.
                bitmap id # to use for icon: 0x636c6163
WM_NORMAL_HINTS(WM_SIZE_HINTS):
                program specified size: 226 by 394
                window gravity: NorthWest
WM_CLIENT_MACHINE(STRING) = "IESOUIP-OIDMS1P"
WM_COMMAND(STRING) = { "xcalc" }
WM_ICON_NAME(STRING) = "Calc"
WM_NAME(STRING) = "Calculator"

For windows

For Microsoft windows, there are multiple alternatives, to xwininfo, and xprop, that can be used. The most prominent one, is the Spy++ application.

Spy++, allows to to display a list of all the windows. Additionally, for each listed window, you can get a list of its attributes, such as its bounding rectangle, its window procedure, its extended and window styles, the process and thread ids, which have created the window …

Additionally, Spy++ allows to view the messages, which are delivered to a window, such as WM_CREATE, for when the window is created, or WM_KEYDOWN , for when a key is down.





The Spy++ application, can be downloaded from here . It can also be installed, by installing visual studio.

Additional information, about Spy++, can be found here .

macOS

For Apple macOS, there is no software, similar to Spy++, which can be used to list all the windows, and their attributes, but this can be done using the following code.

#import <Cocoa/Cocoa.h>
#include <stdio.h>

CFComparisonResult 
            sortWindow 
        (CFDictionaryRef window_1, CFDictionaryRef window_2, CFStringCompareFlags compareOptions ){
        //Sort windows using their window number 
    NSInteger window_number_1 = [[window_1 objectForKey:(id ) kCGWindowNumber ] integerValue ];
    NSInteger window_number_2 = [[window_2 objectForKey:(id ) kCGWindowNumber ] integerValue ];
    if (window_number_1 > window_number_2 )
        return kCFCompareGreaterThan;
    else if (window_number_1 < window_number_2 )
        return kCFCompareLessThan;
    return kCFCompareEqualTo; }

int 
            main
        (int argc, char* argv[ ] ){

    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc ] init ];
    NSArray* windows =  [(NSArray* ) CGWindowListCopyWindowInfo (kCGWindowListOptionOnScreenOnly, kCGNullWindowID ) autorelease ];
    /* Generate and return information about windows, in current user session,
         kCGWindowListOptionOnScreenOnly will list all the windows,
         which are currently on screen  .*/
    CFArraySortValues (windows,
                CFRangeMake (0, CFArrayGetCount (windows )),
                (CFComparatorFunction ) sortWindow,
                NULL);
    /* Sort the windows */


    NSInteger window_number;
    NSString* window_application_owner_name;
    NSInteger window_application_owner_pid;
    CGRect window_rectangle;

    printf ("Window Number    Application Name    Process ID    X         Y      W      H\n");
    printf ("-----------------------------------------------------------------------------\n");

    for ( NSDictionary* window in windows ){
        window_number = [[window objectForKey:(id ) kCGWindowNumber ] integerValue ];
        window_application_owner_name = [window objectForKey:(id ) kCGWindowOwnerName ];
        window_application_owner_pid = [[window objectForKey:(id ) kCGWindowOwnerPID ] integerValue ];
        CGRectMakeWithDictionaryRepresentation (CFDictionaryGetValue (window, kCGWindowBounds ),
                                               &window_rectangle );
        printf ("%-16d %-24s %-8d %-4.0f %6.0f %6.0f %6.0f\n",
                window_number, 
                [window_application_owner_name UTF8String ],
                window_application_owner_pid,
                window_rectangle .origin .x,
                window_rectangle .origin .y,
                window_rectangle .size .width,
                window_rectangle .size .height); }
    [pool release]; }

/* 
$ nano list_windows.m
$ gcc -framework Cocoa list_windows.m
$ ./a.out 

Output:
Window Number    Application Name    Process ID    X         Y      W      H
-----------------------------------------------------------------------------
2                Window Server            58       0         0   1366    768
6                Window Server            58       0         0   1366     22
11               Finder                   121      0         0   1366    768
12               Window Server            58       0        22   1366     14
13               SystemUIServer           120      1320      0     46     22
14               SystemUIServer           120      1091      0    229     22
15               SystemUIServer           120      0         0   1366     22
17               Dock                     119      0        22   1366    746
20               Dock                     119      26      718   1314     50
26               Terminal                 171      306      82    865    548
*/