Linux: get name of window manager
Posted: Thu Jan 31, 2008 11:50 pm
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.
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()