;;; xcb-icccm.el --- Inter-Client Communication -*- lexical-binding: t -*- ;;; Conventions Manual ;; Copyright (C) 2015-2019 Free Software Foundation, Inc. ;; Author: Chris Feng ;; This file is part of GNU Emacs. ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs. If not, see . ;;; Commentary: ;; This library implements ICCCM the same way as xcb/util-wm. ;; Usage tips: ;; + Do not forget to call `xcb:icccm:init' for _every_ connection using ;; this library. ;; + Use `xcb:icccm:SendEvent' instead of `xcb:SendEvent' to send client ;; messages defined in this library. ;; Todo: ;; + Interned atoms are actually connection-dependent. Currently they are ;; simply saved as global variables. ;; References: ;; + ICCCM (http://www.x.org/releases/X11R7.7/doc/xorg-docs/icccm/icccm.txt) ;; + xcb/util-wm (git://anongit.freedesktop.org/xcb/util-wm) ;;; Code: (eval-when-compile (require 'cl-lib)) (require 'xcb) ;;;; ICCCM atoms (eval-and-compile (defconst xcb:icccm:-atoms '(UTF8_STRING COMPOUND_TEXT TEXT C_STRING MANAGER WM_PROTOCOLS WM_TAKE_FOCUS WM_DELETE_WINDOW WM_STATE WM_CHANGE_STATE WM_S0) "Atoms involved in ICCCM.") (dolist (atom xcb:icccm:-atoms) (eval `(defvar ,(intern (concat "xcb:Atom:" (symbol-name atom))) nil)))) (cl-defmethod xcb:icccm:init ((obj xcb:connection) &optional force) "Initialize ICCCM module. This method must be called before using any other method in this module." (when (or force (not xcb:Atom:WM_PROTOCOLS)) (let ((atoms xcb:icccm:-atoms)) (dotimes (i (1- (x-display-screens))) (push (intern (format "WM_S%d" (1+ i))) atoms)) (xcb:icccm:intern-atoms obj atoms force)))) (cl-defmethod xcb:icccm:intern-atoms ((obj xcb:connection) atoms &optional force) "Intern the X atoms listed in the list ATOMS. The value of these atoms will be available in `xcb:Atom' namespace." (dolist (atom atoms) (let* ((name (symbol-name atom)) (var-name (intern (concat "xcb:Atom:" name)))) (when (or force (not (and (boundp var-name) (symbol-value var-name)))) (set var-name (slot-value (xcb:+request-unchecked+reply obj (make-instance 'xcb:InternAtom :only-if-exists 0 :name-len (length name) :name name)) 'atom)))))) ;;;; Client message (defclass xcb:icccm:SendEvent (xcb:SendEvent) ((propagate :initform 0) (event-mask :initform xcb:EventMask:NoEvent)) :documentation "A fork of `xcb:SendEvent' to send ICCCM client messages.") (defclass xcb:icccm:--ClientMessage (xcb:--struct) ((data :type xcb:-ignore)) ;shadowed slot :documentation "To shadow the data slot in `xcb:ClientMessage'.") ;; (defclass xcb:icccm:-ClientMessage (xcb:icccm:--ClientMessage xcb:ClientMessage) ((format :initform 32) (type :initform xcb:Atom:WM_PROTOCOLS) (protocol :type xcb:ATOM) ;new slot (time :initarg :time :type xcb:TIMESTAMP) ;new slot (pad~0 :initform 12 :type xcb:-pad)) ;new slot :documentation "An ICCCM client message with data slot replaced by protocol and time.") (defclass xcb:icccm:WM_DELETE_WINDOW (xcb:icccm:-ClientMessage) ((protocol :initform xcb:Atom:WM_DELETE_WINDOW) (time :initform xcb:Time:CurrentTime)) :documentation "Delete a window using the WM_DELETE_WINDOW client message.") (defclass xcb:icccm:WM_TAKE_FOCUS (xcb:icccm:-ClientMessage) ((protocol :initform xcb:Atom:WM_TAKE_FOCUS)) :documentation "Set a focus using the WM_TAKE_FOCUS client message. A valid timestamp (rather than `xcb:Time:CurrentTime') must be supplied.") ;;;; Abstract classes for getting/changing (plain) list properties (defclass xcb:icccm:-GetProperty (xcb:GetProperty) ((delete :initform 0) (long-offset :initform 0) (long-length :initform 1000000000.)) ;as long as possible :documentation "Get an ICCCM property (request part).") (defclass xcb:icccm:-GetProperty~reply (xcb:GetProperty~reply) nil :documentation "Get an ICCCM property (reply part).") ;; (cl-defmethod xcb:unmarshal ((obj xcb:icccm:-GetProperty~reply) byte-array) "Fill in the fields in the reply of ICCCM GetProperty request OBJ according to BYTE-ARRAY. This method automatically format the value as 8, 16 or 32 bits array." (let ((retval (cl-call-next-method obj byte-array)) tmp) (with-slots (~lsb length format value-len value) obj (if (or (= 0 value-len) (= 0 length)) (setf value nil) ;no available value (setq tmp value ;long-offset is always 0 value nil) (pcase format (8 (cl-assert (= value-len (length tmp))) (setf value tmp)) (16 (cl-assert (= (* 2 value-len) (length tmp))) (if ~lsb (dotimes (_ value-len) (setf value (vconcat value (vector (xcb:-unpack-u2-lsb tmp 0)))) (setq tmp (substring tmp 2))) (dotimes (_ value-len) (setf value (vconcat value (vector (xcb:-unpack-u2 tmp 0)))) (setq tmp (substring tmp 2))))) (32 (cl-assert (= (* 4 value-len) (length tmp))) (if ~lsb (dotimes (_ value-len) (setf value (vconcat value (vector (xcb:-unpack-u4-lsb tmp 0)))) (setq tmp (substring tmp 4))) (dotimes (_ value-len) (setf value (vconcat value (vector (xcb:-unpack-u4 tmp 0)))) (setq tmp (substring tmp 4))))) (_ (cl-assert nil))))) retval)) (defclass xcb:icccm:-ChangeProperty (xcb:ChangeProperty) ((mode :initform xcb:PropMode:Replace) (format :initform 32) (data :initform nil)) :documentation "Change an ICCCM property.") ;; (cl-defmethod xcb:marshal ((obj xcb:icccm:-ChangeProperty)) "Return the byte-array representation of an ICCCM ChangeProperty request. This method automatically sets the data length." (with-slots (~lsb format data-len data) obj (setf data-len (length data)) (setf data (pcase format (8 data) (16 (mapconcat (lambda (i) (if ~lsb (xcb:-pack-u2-lsb i) (xcb:-pack-u2 i))) data [])) (32 (mapconcat (lambda (i) (if ~lsb (xcb:-pack-u4-lsb i) (xcb:-pack-u4 i))) data [])) (_ (cl-assert nil))))) (cl-call-next-method obj)) ;;;; Abstract classes for getting/changing text properties (defclass xcb:icccm:-GetProperty-text (xcb:icccm:-GetProperty) ((type :initform xcb:GetPropertyType:Any)) :documentation "Get an ICCCM text property (request part).") (defclass xcb:icccm:-GetProperty-text~reply (xcb:icccm:-GetProperty~reply) nil :documentation "Get an ICCCM text property (reply part).") ;; (cl-defmethod xcb:unmarshal ((obj xcb:icccm:-GetProperty-text~reply) byte-array) "Fill in the fields in the reply of ICCCM GetProperty (text) request OBJ according to BYTE-ARRAY. This method automatically decodes the value (as string)." (let* ((retval (cl-call-next-method obj byte-array))) (with-slots (format type value) obj (when (symbolp type) (setq type (symbol-value type))) (when (and value (= format 8)) (setf value (decode-coding-string (apply #'unibyte-string (append value nil)) (cond ((= type xcb:Atom:UTF8_STRING) 'utf-8) ((= type xcb:Atom:STRING) 'iso-latin-1) ((= type xcb:Atom:COMPOUND_TEXT) 'compound-text-with-extensions) ((or (eq type xcb:Atom:TEXT) (eq type xcb:Atom:C_STRING)) 'no-conversion) (t (error "[XELB:ICCCM] Unsupported encoding: %d" type))))))) retval)) (defclass xcb:icccm:-ChangeProperty-text (xcb:icccm:-ChangeProperty) ((type :initform xcb:Atom:STRING) ;may be changed (format :initform 8)) :documentation "Change an ICCCM text property.") ;; (cl-defmethod xcb:marshal ((obj xcb:icccm:-ChangeProperty-text)) "Return the byte-array representation of an ICCCM ChangeProperty (text) request OBJ. This method automatically encodes the data (which is a string)." (with-slots (type data) obj (when (symbolp type) (setq type (symbol-value type))) (setf data (vconcat (encode-coding-string data (cond ((= type xcb:Atom:UTF8_STRING) 'utf-8) ((= type xcb:Atom:STRING) 'iso-latin-1) ((= type xcb:Atom:COMPOUND_TEXT) 'compound-text-with-extensions) ((or (eq type xcb:Atom:TEXT) (eq type xcb:Atom:C_STRING)) 'no-conversion) (t (error "[XELB:ICCCM] Unsupported encoding: %d" type))))))) (cl-call-next-method obj)) ;;;; Abstract classes for getting/changing single field properties (defclass xcb:icccm:-GetProperty-single (xcb:icccm:-GetProperty) nil :documentation "Get an ICCCM single-valued property (request part).") (defclass xcb:icccm:-GetProperty-single~reply (xcb:icccm:-GetProperty~reply) nil :documentation "Get a single-valued ICCCM property (reply part).") ;; (cl-defmethod xcb:unmarshal ((obj xcb:icccm:-GetProperty-single~reply) byte-array) "Fill in the fields in the reply of an ICCCM GetProperty (single-valued) request OBJ according to BYTE-ARRAY." (let ((retval (cl-call-next-method obj byte-array))) (with-slots (value) obj (when value (cl-assert (= 1 (length value))) (setf value (elt value 0)))) retval)) (defclass xcb:icccm:-ChangeProperty-single (xcb:icccm:-ChangeProperty) nil :documentation "Change a single-valued ICCCM property.") ;; (cl-defmethod xcb:marshal ((obj xcb:icccm:-ChangeProperty-single)) "Return the byte-array representation of a single-valued ICCCM ChangeProperty request OBJ." (with-slots (data) obj (setf data `[,data])) (cl-call-next-method obj)) ;;;; Abstract classes for getting/changing property with explicit fields (defclass xcb:icccm:-GetProperty-explicit (xcb:icccm:-GetProperty) nil :documentation "Get an ICCCM property whose fields are explicitly listed out (request part).") (defclass xcb:icccm:-GetProperty-explicit~reply (xcb:icccm:-GetProperty~reply) nil :documentation "Get an ICCCM property whose fields are explicitly listed out (reply part).") ;; (cl-defmethod xcb:unmarshal ((obj xcb:icccm:-GetProperty-explicit~reply) byte-array) "Fill in the reply of an ICCCM GetProperty request whose fields are explicitly listed out." (let* ((retval (cl-call-next-method obj byte-array)) (slots-orig (eieio-class-slots 'xcb:icccm:-GetProperty~reply)) (slots (eieio-class-slots (eieio-object-class obj))) (slots (nthcdr (length slots-orig) slots)) (value (slot-value obj 'value))) (unless value (setq value (make-vector (length slots) nil))) ;fallback ;; Set explicit fields from value field (dotimes (i (length value)) (setf (slot-value obj (eieio-slot-descriptor-name (elt slots i))) (elt value i))) retval)) (defclass xcb:icccm:-ChangeProperty-explicit (xcb:icccm:-ChangeProperty) ((format :initform 32)) :documentation "Change an ICCCM property whose fields are explicitly listed out.") ;; (cl-defmethod xcb:marshal ((obj xcb:icccm:-ChangeProperty-explicit)) "Return the byte-array representation of an ICCCM ChangeProperty request whose fields are explicitly listed out." (let* ((slots-orig (eieio-class-slots 'xcb:icccm:-ChangeProperty)) (slots (eieio-class-slots (eieio-object-class obj))) (slots (nthcdr (length slots-orig) slots))) ;; Set data field from explicit fields (setf (slot-value obj 'data) (mapconcat (lambda (slot) (list (slot-value obj (eieio-slot-descriptor-name slot)))) slots [])) (cl-call-next-method obj))) ;;;; Client Properties ;; WM_NAME (defclass xcb:icccm:get-WM_NAME (xcb:icccm:-GetProperty-text) ((property :initform xcb:Atom:WM_NAME))) (defclass xcb:icccm:get-WM_NAME~reply (xcb:icccm:-GetProperty-text~reply) nil) (defclass xcb:icccm:set-WM_NAME (xcb:icccm:-ChangeProperty-text) ((property :initform xcb:Atom:WM_NAME))) ;; WM_ICON_NAME (defclass xcb:icccm:get-WM_ICON_NAME (xcb:icccm:-GetProperty-text) ((property :initform xcb:Atom:WM_ICON_NAME))) (defclass xcb:icccm:get-WM_ICON_NAME~reply (xcb:icccm:-GetProperty-text~reply) nil) (defclass xcb:icccm:set-WM_ICON_NAME (xcb:icccm:-ChangeProperty-text) ((property :initform xcb:Atom:WM_ICON_NAME))) ;; WM_SIZE_HINTS (defconst xcb:icccm:WM_SIZE_HINTS:USPosition 1) (defconst xcb:icccm:WM_SIZE_HINTS:USSize 2) (defconst xcb:icccm:WM_SIZE_HINTS:PPosition 4) (defconst xcb:icccm:WM_SIZE_HINTS:PSize 8) (defconst xcb:icccm:WM_SIZE_HINTS:PMinSize 16) (defconst xcb:icccm:WM_SIZE_HINTS:PMaxSize 32) (defconst xcb:icccm:WM_SIZE_HINTS:PResizeInc 64) (defconst xcb:icccm:WM_SIZE_HINTS:PAspect 128) (defconst xcb:icccm:WM_SIZE_HINTS:PBaseSize 256) (defconst xcb:icccm:WM_SIZE_HINTS:PWinGravity 512) ;; (defclass xcb:icccm:-WM_SIZE_HINTS (xcb:--struct) ((flags :initarg :flags :initform 0 :type xcb:-ignore) (x :initarg :x :initform 0 :type xcb:-ignore) (y :initarg :y :initform 0 :type xcb:-ignore) (width :initarg :width :initform 0 :type xcb:-ignore) (height :initarg :height :initform 0 :type xcb:-ignore) (min-width :initarg :min-width :initform 0 :type xcb:-ignore) (min-height :initarg :min-height :initform 0 :type xcb:-ignore) (max-width :initarg :max-width :initform 0 :type xcb:-ignore) (max-height :initarg :max-height :initform 0 :type xcb:-ignore) (width-inc :initarg :width-inc :initform 0 :type xcb:-ignore) (height-inc :initarg :height-inc :initform 0 :type xcb:-ignore) (min-aspect-num :initarg :min-aspect-num :initform 0 :type xcb:-ignore) (min-aspect-den :initarg :min-aspect-den :initform 0 :type xcb:-ignore) (max-aspect-num :initarg :max-aspect-num :initform 0 :type xcb:-ignore) (max-aspect-den :initarg :max-aspect-den :initform 0 :type xcb:-ignore) (base-width :initarg :base-width :initform 0 :type xcb:-ignore) (base-height :initarg :base-height :initform 0 :type xcb:-ignore) (win-gravity :initarg :win-gravity :initform 0 :type xcb:-ignore))) ;; (defclass xcb:icccm:get-WM_SIZE_HINTS (xcb:icccm:-GetProperty-explicit) ((property :initform xcb:Atom:WM_SIZE_HINTS) (type :initform xcb:Atom:WM_SIZE_HINTS) (long-length :initform 18))) ;fixed (defclass xcb:icccm:get-WM_SIZE_HINTS~reply (xcb:icccm:-GetProperty-explicit~reply xcb:icccm:-WM_SIZE_HINTS) nil) (defclass xcb:icccm:set-WM_SIZE_HINTS (xcb:icccm:-ChangeProperty-explicit xcb:icccm:-WM_SIZE_HINTS) ((property :initform xcb:Atom:WM_SIZE_HINTS) (type :initform xcb:Atom:WM_SIZE_HINTS))) ;; WM_NORMAL_HINTS (defclass xcb:icccm:get-WM_NORMAL_HINTS (xcb:icccm:get-WM_SIZE_HINTS) ((property :initform xcb:Atom:WM_NORMAL_HINTS))) (defclass xcb:icccm:get-WM_NORMAL_HINTS~reply (xcb:icccm:get-WM_SIZE_HINTS~reply) nil) (defclass xcb:icccm:set-WM_NORMAL_HINTS (xcb:icccm:set-WM_SIZE_HINTS) ((property :initform xcb:Atom:WM_NORMAL_HINTS))) ;; WM_HINTS (defconst xcb:icccm:WM_HINTS:InputHint 1) (defconst xcb:icccm:WM_HINTS:StateHint 2) (defconst xcb:icccm:WM_HINTS:IconPixmapHint 4) (defconst xcb:icccm:WM_HINTS:IconWindowHint 8) (defconst xcb:icccm:WM_HINTS:IconPositionHint 16) (defconst xcb:icccm:WM_HINTS:IconMaskHint 32) (defconst xcb:icccm:WM_HINTS:WindowGroupHint 64) (defconst xcb:icccm:WM_HINTS:MessageHint 128) (defconst xcb:icccm:WM_HINTS:UrgencyHint 256) ;; (defclass xcb:icccm:-WM_HINTS (xcb:--struct) ((flags :initarg :flags :initform 0 :type xcb:-ignore) (input :initarg :input :initform 0 :type xcb:-ignore) (initial-state :initarg :initial-state :initform 0 :type xcb:-ignore) (icon-pixmap :initarg :icon-pixmap :initform 0 :type xcb:-ignore) (icon-window :initarg :icon-window :initform 0 :type xcb:-ignore) (icon-x :initarg :icon-x :initform 0 :type xcb:-ignore) (icon-y :initarg :icon-y :initform 0 :type xcb:-ignore) (icon-mask :initarg :icon-mask :initform 0 :type xcb:-ignore) (window-group :initarg :window-group :initform 0 :type xcb:-ignore))) ;; (defclass xcb:icccm:get-WM_HINTS (xcb:icccm:-GetProperty-explicit) ;; (xcb:icccm:-GetProperty) ((property :initform xcb:Atom:WM_HINTS) (type :initform xcb:Atom:WM_HINTS) (long-length :initform 9))) ;fixed (defclass xcb:icccm:get-WM_HINTS~reply (xcb:icccm:-GetProperty-explicit~reply xcb:icccm:-WM_HINTS) nil) (defclass xcb:icccm:set-WM_HINTS (xcb:icccm:-ChangeProperty-explicit xcb:icccm:-WM_HINTS) ((property :initform xcb:Atom:WM_HINTS) (type :initform xcb:Atom:WM_HINTS))) ;; WM_CLASS (defclass xcb:icccm:get-WM_CLASS (xcb:icccm:-GetProperty-text) ((property :initform xcb:Atom:WM_CLASS) (type :initform xcb:Atom:STRING))) (defclass xcb:icccm:get-WM_CLASS~reply (xcb:icccm:-GetProperty-text~reply) ((instance-name :type xcb:-ignore) (class-name :type xcb:-ignore))) ;; (cl-defmethod xcb:unmarshal ((obj xcb:icccm:get-WM_CLASS~reply) byte-array) ;; Split value into instance & class names (let* ((retval (cl-call-next-method obj byte-array)) (tmp (slot-value obj 'value)) (tmp (if tmp (split-string tmp "\0" t) '(nil nil)))) (with-slots (instance-name class-name) obj (setf instance-name (car tmp) class-name (cadr tmp))) retval)) ;; (defclass xcb:icccm:set-WM_CLASS (xcb:icccm:-ChangeProperty-text) ((property :initform xcb:Atom:WM_CLASS) (type :initform xcb:Atom:STRING) (instance-name :initarg :instance-name :type xcb:-ignore) (class-name :initarg :class-name :type xcb:-ignore))) ;; (cl-defmethod xcb:marshal ((obj xcb:icccm:set-WM_CLASS)) (with-slots (data instance-name class-name) obj (setf data (concat instance-name "\0" class-name "\0"))) (cl-call-next-method obj)) ;; WM_TRANSIENT_FOR (defclass xcb:icccm:get-WM_TRANSIENT_FOR (xcb:icccm:-GetProperty-single) ((property :initform xcb:Atom:WM_TRANSIENT_FOR) (type :initform xcb:Atom:WINDOW) (long-length :initform 1))) (defclass xcb:icccm:get-WM_TRANSIENT_FOR~reply (xcb:icccm:-GetProperty-single~reply) nil) (defclass xcb:icccm:set-WM_TRANSIENT_FOR (xcb:icccm:-ChangeProperty-single) ((property :initform xcb:Atom:WM_TRANSIENT_FOR) (type :initform xcb:Atom:WINDOW))) ;; WM_PROTOCOLS (defclass xcb:icccm:get-WM_PROTOCOLS (xcb:icccm:-GetProperty) ((property :initform xcb:Atom:WM_PROTOCOLS) (type :initform xcb:Atom:ATOM))) (defclass xcb:icccm:get-WM_PROTOCOLS~reply (xcb:icccm:-GetProperty~reply) nil) (defclass xcb:icccm:set-WM_PROTOCOLS (xcb:icccm:-ChangeProperty) ((type :initform xcb:Atom:ATOM) (format :initform 32))) ;; WM_COLORMAP_WINDOWS (defclass xcb:icccm:get-WM_COLORMAP_WINDOWS (xcb:icccm:-GetProperty) ((type :initform xcb:Atom:WINDOW))) (defclass xcb:icccm:get-WM_COLORMAP_WINDOWS~reply (xcb:icccm:-GetProperty~reply) nil) (defclass xcb:icccm:set-WM_COLORMAP_WINDOWS (xcb:icccm:-ChangeProperty) ((type :initform xcb:Atom:WINDOW) (format :initform 32))) ;; WM_CLIENT_MACHINE (defclass xcb:icccm:get-WM_CLIENT_MACHINE (xcb:icccm:-GetProperty-text) ((property :initform xcb:Atom:WM_CLIENT_MACHINE))) (defclass xcb:icccm:get-WM_CLIENT_MACHINE~reply (xcb:icccm:-GetProperty-text~reply) nil) (defclass xcb:icccm:set-WM_CLIENT_MACHINE (xcb:icccm:-ChangeProperty-text) ((property :initform xcb:Atom:WM_CLIENT_MACHINE))) ;;;; Window Manager Properties ;; WM_STATE (defconst xcb:icccm:WM_STATE:WithdrawnState 0) (defconst xcb:icccm:WM_STATE:NormalState 1) (defconst xcb:icccm:WM_STATE:IconicState 3) ;; (defclass xcb:icccm:-WM_STATE (xcb:--struct) ((state :initarg :state :type xcb:-ignore) (icon :initarg :icon :type xcb:-ignore))) ;; (defclass xcb:icccm:get-WM_STATE (xcb:icccm:-GetProperty-explicit) ((property :initform xcb:Atom:WM_STATE) (type :initform xcb:Atom:WM_STATE) (long-length :initform 2))) (defclass xcb:icccm:get-WM_STATE~reply (xcb:icccm:-GetProperty-explicit~reply xcb:icccm:-WM_STATE) nil) (defclass xcb:icccm:set-WM_STATE (xcb:icccm:-ChangeProperty-explicit xcb:icccm:-WM_STATE) ((property :initform xcb:Atom:WM_STATE) (type :initform xcb:Atom:WM_STATE))) ;; WM_ICON_SIZE (defclass xcb:icccm:-WM_ICON_SIZE (xcb:--struct) ((min-width :initarg :min-width :type xcb:-ignore) (min-height :initarg :min-height :type xcb:-ignore) (max-width :initarg :max-width :type xcb:-ignore) (max-height :initarg :max-height :type xcb:-ignore) (width-inc :initarg :width-inc :type xcb:-ignore) (height-inc :initarg :height-inc :type xcb:-ignore))) ;; (defclass xcb:icccm:get-WM_ICON_SIZE (xcb:icccm:-GetProperty-explicit) ((property :initform xcb:Atom:WM_ICON_SIZE) (type :initform xcb:Atom:WM_ICON_SIZE) (long-length :initform 6))) (defclass xcb:icccm:get-WM_ICON_SIZE~reply (xcb:icccm:-GetProperty-explicit~reply xcb:icccm:-WM_ICON_SIZE) nil) (defclass xcb:icccm:set-WM_ICON_SIZE (xcb:icccm:-ChangeProperty-explicit xcb:icccm:-WM_ICON_SIZE) ((property :initform xcb:Atom:WM_ICON_SIZE) (type :initform xcb:Atom:WM_ICON_SIZE))) (provide 'xcb-icccm) ;;; xcb-icccm.el ends here