Linux: get name of window manager

Share your advanced PureBasic knowledge/code with the community.
freak
PureBasic Team
PureBasic Team
Posts: 5944
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Linux: get name of window manager

Post by freak »

Wrote this for pcfreak on the IRC channel:

It reads the name of the current running window manager (if any).
The window manager has to conform to the window manager hint spec, which
is the case for most window managers today i think.
The format of the returned string depends on the window manager used.
It could be just a name, or a name + a version number etc.

Code: Select all

; ---------------------------------------------------
; To access the X display from Gtk:
; ---------------------------------------------------

CompilerIf Subsystem("gtk1")

  Structure GdkWindow ; this is actually the full struct def
    user_data.l
  EndStructure

  ;// this is gtk1 only. it is an internal Structure from the sources
  ;// the internal representation of a GtkWindow
  Structure GdkWindowPrivate   
    window.GdkWindow
    *parent
    xwindow.l
    xdisplay.l
    ; incomplete definition... too lazy :)     
  EndStructure
  
  Procedure XDisplayFromWindowID(*Window.GtkWidget)  
    *gdkwindow.GdkWindow = *Window\window
    ProcedureReturn *gdkwindow\xdisplay
  EndProcedure
 
CompilerElse

  Structure _GdkScreen Extends GdkScreen ; PB def seems to be incomplete
    *font_options;
    resolution.d;      /* pixels/points scale factor for fonts */
  EndStructure
 
 
  Structure GdkScreenX11
    parent_instance._GdkScreen;
   
    *display;
    *xdisplay;
    *xscreen;
   
    ; incomplete def!
  EndStructure
 
  Structure GdkDrawableImplX11
    parent_instance.GdkDrawable
    *wrapper;
    *colormap;
   
    xid.l
    *screen
 
    picture.l ;Picture
    *cairo_surface;
  EndStructure
 
  Structure _GdkWindowObject ; PB def is empty!
    parent_instance.GdkDrawable;
    *impl.GdkDrawable ; /* window-system-specific delegate object */ 
    *parent;
    user_data.l
    ; incomplete def!
  EndStructure

  ;#define GDK_WINDOW_XDISPLAY(win)      (GDK_SCREEN_X11 (GDK_WINDOW_SCREEN (win))->xdisplay)   
  ;#define GDK_WINDOW_XID(win)           (GDK_DRAWABLE_IMPL_X11(((GdkWindowObject *)win)->impl)->xid)
  ;#define GDK_WINDOW_SCREEN(win)         (GDK_DRAWABLE_IMPL_X11 (((GdkWindowObject *)win)->impl)->screen)
  ;#define GDK_SCREEN_X11(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_SCREEN_X11, GdkScreenX11))
  ;#define GDK_DRAWABLE_IMPL_X11(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DRAWABLE_IMPL_X11, GdkDrawableImplX11))
   
  Procedure XDisplayFromWindowID(*Window.GtkWidget)  
    *gdkwindowobj._GdkWindowObject = *Window\window
    *impl.GdkDrawableImplX11 = *gdkwindowobj\impl
    *screen.GdkScreenX11 = *impl\screen
    ProcedureReturn *screen\xdisplay       
  EndProcedure   
   
CompilerEndIf


; ---------------------------------------------------
; Required XLib stuff:
; ---------------------------------------------------

ImportC "-lX11" ; link with XLib even if no gui commands are used
  XOpenDisplay(display_name)
  XCloseDisplay(display)
  XInternAtom(display, name.p-ascii, only_if_exists)
  XFree(pdata)
  XDefaultRootWindow(display)
  XGetWindowProperty(display, w, property, long_offset, long_length, delete, req_type, actual_type_return, actual_format_return, nitems_return, bytes_after_return, prop_return)
  XGetWMName(display, w, text_prop_return)
EndImport


#Success = 0

; If WindowID != 0 (a result from WindowID()), the current X display from gtk is used
; Else a new X connection is opened just for this command, so this also works if 
; no GUI commands are used.
;
; If the program has open windows, it is advised to use one of them here
; to avoid the extra X connection.
;
; If there is no window manager that complies to the WM manager hints is present,
; the result is an empty string
;
Procedure.s GetWindowManager(WindowID = 0)
  Result$ = ""

  If WindowID 
    xdisplay = XDisplayFromWindowID(WindowID)
  Else
    ; uses the default DISPLAY environment variable
    ; can also be a display string, needs to be ascii though!
    ;
    xdisplay = XOpenDisplay(#Null) 
  EndIf
  
  If xdisplay
  
    _NET_SUPPORTING_WM_CHECK = XInternAtom(xdisplay, "_NET_SUPPORTING_WM_CHECK", #False)
    _NET_WM_NAME             = XInternAtom(xdisplay, "_NET_WM_NAME", #False)
    WINDOW_PROPERTY          = XInternAtom(xdisplay, "WINDOW", #False)
    UTF8_PROPERTY            = XInternAtom(xdisplay, "UTF8_STRING", #False)
    
    ; read the _NET_SUPPORTING_WM_CHECK from the X root window
    ;
    If XGetWindowProperty(xdisplay, XDefaultRootWindow(xdisplay), _NET_SUPPORTING_WM_CHECK, 0, 32, #False, WINDOW_PROPERTY, @rettype, @retformat, @retitems, @retbytes, @resultdata) = #Success And resultdata
      If rettype = WINDOW_PROPERTY And retformat = 32 And retitems >= 1
        child = PeekL(resultdata)
        
        ; the child must also have a _NET_SUPPORTING_WM_CHECK according to the specification
        ;
        If XGetWindowProperty(xdisplay, child, _NET_SUPPORTING_WM_CHECK, 0, 32, #False, WINDOW_PROPERTY, @rettype, @retformat, @retitems, @retbytes, @resultdata2) = #Success And resultdata2
          If rettype = WINDOW_PROPERTY And retformat = 32 And retitems >= 1 And PeekL(resultdata2) = child
            
            ; read the _NET_WM_NAME which stores the WM name for complying implementations
            ;
            If XGetWindowProperty(xdisplay, child, _NET_WM_NAME, 0, 6400, #False, UTF8_PROPERTY, @rettype, @retformat, @retitems, @retbytes, @resultstring) = #Success And resultstring
              If rettype = UTF8_PROPERTY And retformat = 8 And retitems >= 1
                Result$ = PeekS(resultstring, -1, #PB_UTF8)
              EndIf
              XFree(resultstring)
            EndIf
  
          EndIf
          XFree(resultdata2)
        EndIf
  
      EndIf
      XFree(resultdata)
    EndIf
    
    If WindowID = 0 
      XCloseDisplay(xdisplay) ; if we opened it, close it again!
    EndIf
  EndIf
    
  ProcedureReturn Result$
EndProcedure


Debug GetWindowManager()
quidquid Latine dictum sit altum videtur
User avatar
Hroudtwolf
Addict
Addict
Posts: 803
Joined: Sat Feb 12, 2005 3:35 am
Location: Germany(Hessen)
Contact:

Post by Hroudtwolf »

Thanks for sharing.
Post Reply