2016-02-19 04:02:37 +01:00
|
|
|
|
;;; exwm-systemtray.el --- System Tray Module for -*- lexical-binding: t -*-
|
|
|
|
|
;;; EXWM
|
|
|
|
|
|
2024-01-08 01:00:00 +01:00
|
|
|
|
;; Copyright (C) 2016-2024 Free Software Foundation, Inc.
|
2016-02-19 04:02:37 +01:00
|
|
|
|
|
|
|
|
|
;; Author: Chris Feng <chris.w.feng@gmail.com>
|
|
|
|
|
|
|
|
|
|
;; 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
|
|
|
|
;; This module adds system tray support for EXWM.
|
|
|
|
|
|
|
|
|
|
;; To use this module, load and enable it as follows:
|
|
|
|
|
;; (require 'exwm-systemtray)
|
|
|
|
|
;; (exwm-systemtray-enable)
|
|
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
2022-11-04 01:00:00 +01:00
|
|
|
|
(require 'xcb-ewmh)
|
2016-04-21 15:37:02 +02:00
|
|
|
|
(require 'xcb-icccm)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(require 'xcb-xembed)
|
|
|
|
|
(require 'xcb-systemtray)
|
2019-02-06 01:00:00 +01:00
|
|
|
|
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(require 'exwm-core)
|
2019-02-06 01:00:00 +01:00
|
|
|
|
(require 'exwm-workspace)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
|
2023-06-09 02:00:00 +02:00
|
|
|
|
(declare-function exwm-workspace--workarea "exwm-workspace.el" (frame))
|
|
|
|
|
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(defclass exwm-systemtray--icon ()
|
|
|
|
|
((width :initarg :width)
|
|
|
|
|
(height :initarg :height)
|
|
|
|
|
(visible :initarg :visible))
|
|
|
|
|
:documentation "Attributes of a system tray icon.")
|
|
|
|
|
|
2016-04-21 15:37:02 +02:00
|
|
|
|
(defclass xcb:systemtray:-ClientMessage
|
|
|
|
|
(xcb:icccm:--ClientMessage xcb:ClientMessage)
|
|
|
|
|
((format :initform 32)
|
2023-08-18 02:00:00 +02:00
|
|
|
|
(type :initform 'xcb:Atom:MANAGER)
|
2016-04-21 15:37:02 +02:00
|
|
|
|
(time :initarg :time :type xcb:TIMESTAMP) ;new slot
|
|
|
|
|
(selection :initarg :selection :type xcb:ATOM) ;new slot
|
|
|
|
|
(owner :initarg :owner :type xcb:WINDOW)) ;new slot
|
|
|
|
|
:documentation "A systemtray client message.")
|
|
|
|
|
|
2018-02-18 17:04:27 +01:00
|
|
|
|
(defgroup exwm-systemtray nil
|
|
|
|
|
"System tray."
|
|
|
|
|
:group 'exwm)
|
|
|
|
|
|
|
|
|
|
(defcustom exwm-systemtray-height nil
|
|
|
|
|
"System tray height.
|
2016-02-19 04:02:37 +01:00
|
|
|
|
|
2018-02-18 17:04:27 +01:00
|
|
|
|
You shall use the default value if using auto-hide minibuffer."
|
|
|
|
|
:type 'integer)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
|
2018-02-18 17:04:27 +01:00
|
|
|
|
(defcustom exwm-systemtray-icon-gap 2
|
|
|
|
|
"Gap between icons."
|
|
|
|
|
:type 'integer)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
|
2022-11-04 01:00:00 +01:00
|
|
|
|
(defvar exwm-systemtray--connection nil "The X connection.")
|
|
|
|
|
|
2020-02-02 01:00:00 +01:00
|
|
|
|
(defvar exwm-systemtray--embedder-window nil "The embedder window.")
|
2022-11-04 01:00:00 +01:00
|
|
|
|
(defvar exwm-systemtray--embedder-window-depth nil
|
|
|
|
|
"The embedder window's depth.")
|
2020-02-02 01:00:00 +01:00
|
|
|
|
|
2022-11-09 01:00:00 +01:00
|
|
|
|
(defcustom exwm-systemtray-background-color 'workspace-background
|
2020-02-02 01:00:00 +01:00
|
|
|
|
"Background color of systemtray.
|
2022-11-04 01:00:00 +01:00
|
|
|
|
This should be a color, the symbol `workspace-background' for the background
|
|
|
|
|
color of current workspace frame, or the symbol `transparent' for transparent
|
|
|
|
|
background.
|
|
|
|
|
|
|
|
|
|
Transparent background is not yet supported when Emacs uses 32-bit depth
|
|
|
|
|
visual, as reported by `x-display-planes'. The X resource \"Emacs.visualClass:
|
|
|
|
|
TrueColor-24\" can be used to force Emacs to use 24-bit depth."
|
2022-11-04 01:00:00 +01:00
|
|
|
|
:type '(choice (const :tag "Transparent" transparent)
|
|
|
|
|
(const :tag "Frame background" workspace-background)
|
|
|
|
|
(color :tag "Color"))
|
2020-02-02 01:00:00 +01:00
|
|
|
|
:initialize #'custom-initialize-default
|
|
|
|
|
:set (lambda (symbol value)
|
2022-11-04 01:00:00 +01:00
|
|
|
|
(when (and (eq value 'transparent)
|
|
|
|
|
(not (exwm-systemtray--transparency-supported-p)))
|
|
|
|
|
(display-warning 'exwm-systemtray
|
|
|
|
|
"Transparent background is not supported yet when \
|
2022-11-04 01:00:00 +01:00
|
|
|
|
using 32-bit depth. Using `workspace-background' instead.")
|
|
|
|
|
(setq value 'workspace-background))
|
2020-02-02 01:00:00 +01:00
|
|
|
|
(set-default symbol value)
|
2022-11-04 01:00:00 +01:00
|
|
|
|
(when (and exwm-systemtray--connection
|
2020-02-02 01:00:00 +01:00
|
|
|
|
exwm-systemtray--embedder-window)
|
2022-11-04 01:00:00 +01:00
|
|
|
|
;; Change the background color for embedder.
|
|
|
|
|
(exwm-systemtray--set-background-color)
|
|
|
|
|
;; Unmap & map to take effect immediately.
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:UnmapWindow
|
|
|
|
|
:window exwm-systemtray--embedder-window))
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:MapWindow
|
|
|
|
|
:window exwm-systemtray--embedder-window))
|
|
|
|
|
(xcb:flush exwm-systemtray--connection))))
|
2020-02-02 01:00:00 +01:00
|
|
|
|
|
2018-02-18 17:04:27 +01:00
|
|
|
|
;; GTK icons require at least 16 pixels to show normally.
|
|
|
|
|
(defconst exwm-systemtray--icon-min-size 16 "Minimum icon size.")
|
2016-02-19 04:02:37 +01:00
|
|
|
|
|
|
|
|
|
(defvar exwm-systemtray--list nil "The icon list.")
|
2018-02-18 17:04:27 +01:00
|
|
|
|
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(defvar exwm-systemtray--selection-owner-window nil
|
|
|
|
|
"The selection owner window.")
|
|
|
|
|
|
2018-02-18 17:04:27 +01:00
|
|
|
|
(defvar xcb:Atom:_NET_SYSTEM_TRAY_S0)
|
2016-07-17 14:00:00 +02:00
|
|
|
|
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(defun exwm-systemtray--embed (icon)
|
2023-08-18 02:00:00 +02:00
|
|
|
|
"Embed an ICON."
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log "Try to embed #x%x" icon)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(let ((info (xcb:+request-unchecked+reply exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:xembed:get-_XEMBED_INFO
|
|
|
|
|
:window icon)))
|
|
|
|
|
width* height* visible)
|
|
|
|
|
(when info
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log "Embed #x%x" icon)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(with-slots (width height)
|
|
|
|
|
(xcb:+request-unchecked+reply exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:GetGeometry :drawable icon))
|
|
|
|
|
(setq height* exwm-systemtray-height
|
|
|
|
|
width* (round (* width (/ (float height*) height))))
|
|
|
|
|
(when (< width* exwm-systemtray--icon-min-size)
|
|
|
|
|
(setq width* exwm-systemtray--icon-min-size
|
|
|
|
|
height* (round (* height (/ (float width*) width)))))
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log "Resize from %dx%d to %dx%d"
|
2016-02-19 04:02:37 +01:00
|
|
|
|
width height width* height*))
|
2016-07-30 13:01:33 +02:00
|
|
|
|
;; Add this icon to save-set.
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:ChangeSaveSet
|
|
|
|
|
:mode xcb:SetMode:Insert
|
|
|
|
|
:window icon))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
;; Reparent to the embedder.
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:ReparentWindow
|
|
|
|
|
:window icon
|
2018-08-13 14:00:00 +02:00
|
|
|
|
:parent exwm-systemtray--embedder-window
|
2016-02-19 04:02:37 +01:00
|
|
|
|
:x 0
|
|
|
|
|
;; Vertically centered.
|
|
|
|
|
:y (/ (- exwm-systemtray-height height*) 2)))
|
|
|
|
|
;; Resize the icon.
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:ConfigureWindow
|
|
|
|
|
:window icon
|
|
|
|
|
:value-mask (logior xcb:ConfigWindow:Width
|
|
|
|
|
xcb:ConfigWindow:Height
|
|
|
|
|
xcb:ConfigWindow:BorderWidth)
|
|
|
|
|
:width width*
|
|
|
|
|
:height height*
|
|
|
|
|
:border-width 0))
|
|
|
|
|
;; Set event mask.
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:ChangeWindowAttributes
|
|
|
|
|
:window icon
|
|
|
|
|
:value-mask xcb:CW:EventMask
|
|
|
|
|
:event-mask (logior xcb:EventMask:ResizeRedirect
|
2016-09-23 12:29:11 +02:00
|
|
|
|
xcb:EventMask:KeyPress
|
2016-02-19 04:02:37 +01:00
|
|
|
|
xcb:EventMask:PropertyChange)))
|
2016-09-23 12:29:11 +02:00
|
|
|
|
;; Grab all keys and forward them to Emacs frame.
|
|
|
|
|
(unless (exwm-workspace--minibuffer-own-frame-p)
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:GrabKey
|
|
|
|
|
:owner-events 0
|
|
|
|
|
:grab-window icon
|
|
|
|
|
:modifiers xcb:ModMask:Any
|
|
|
|
|
:key xcb:Grab:Any
|
|
|
|
|
:pointer-mode xcb:GrabMode:Async
|
|
|
|
|
:keyboard-mode xcb:GrabMode:Async)))
|
2016-02-19 13:18:29 +01:00
|
|
|
|
(setq visible (slot-value info 'flags))
|
|
|
|
|
(if visible
|
|
|
|
|
(setq visible
|
|
|
|
|
(/= 0 (logand (slot-value info 'flags) xcb:xembed:MAPPED)))
|
|
|
|
|
;; Default to visible.
|
|
|
|
|
(setq visible t))
|
|
|
|
|
(when visible
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log "Map the window")
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:MapWindow :window icon)))
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:xembed:SendEvent
|
|
|
|
|
:destination icon
|
|
|
|
|
:event
|
|
|
|
|
(xcb:marshal
|
|
|
|
|
(make-instance 'xcb:xembed:EMBEDDED-NOTIFY
|
|
|
|
|
:window icon
|
|
|
|
|
:time xcb:Time:CurrentTime
|
2018-08-13 14:00:00 +02:00
|
|
|
|
:embedder
|
|
|
|
|
exwm-systemtray--embedder-window
|
2016-02-19 04:02:37 +01:00
|
|
|
|
:version 0)
|
|
|
|
|
exwm-systemtray--connection)))
|
|
|
|
|
(push `(,icon . ,(make-instance 'exwm-systemtray--icon
|
|
|
|
|
:width width*
|
|
|
|
|
:height height*
|
|
|
|
|
:visible visible))
|
|
|
|
|
exwm-systemtray--list)
|
|
|
|
|
(exwm-systemtray--refresh))))
|
|
|
|
|
|
|
|
|
|
(defun exwm-systemtray--unembed (icon)
|
2023-08-18 02:00:00 +02:00
|
|
|
|
"Unembed an ICON."
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log "Unembed #x%x" icon)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:UnmapWindow :window icon))
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:ReparentWindow
|
|
|
|
|
:window icon
|
|
|
|
|
:parent exwm--root
|
|
|
|
|
:x 0 :y 0))
|
|
|
|
|
(setq exwm-systemtray--list
|
|
|
|
|
(assq-delete-all icon exwm-systemtray--list))
|
|
|
|
|
(exwm-systemtray--refresh))
|
|
|
|
|
|
|
|
|
|
(defun exwm-systemtray--refresh ()
|
|
|
|
|
"Refresh the system tray."
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
;; Make sure to redraw the embedder.
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
2018-08-13 14:00:00 +02:00
|
|
|
|
(make-instance 'xcb:UnmapWindow
|
|
|
|
|
:window exwm-systemtray--embedder-window))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(let ((x exwm-systemtray-icon-gap)
|
|
|
|
|
map)
|
|
|
|
|
(dolist (pair exwm-systemtray--list)
|
|
|
|
|
(when (slot-value (cdr pair) 'visible)
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:ConfigureWindow
|
|
|
|
|
:window (car pair)
|
|
|
|
|
:value-mask xcb:ConfigWindow:X
|
|
|
|
|
:x x))
|
|
|
|
|
(setq x (+ x (slot-value (cdr pair) 'width)
|
|
|
|
|
exwm-systemtray-icon-gap))
|
|
|
|
|
(setq map t)))
|
2023-06-09 02:00:00 +02:00
|
|
|
|
(let ((workarea (exwm-workspace--workarea exwm-workspace-current-index)))
|
2018-02-19 15:40:27 +01:00
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:ConfigureWindow
|
2018-08-13 14:00:00 +02:00
|
|
|
|
:window exwm-systemtray--embedder-window
|
2018-02-19 15:40:27 +01:00
|
|
|
|
:value-mask (logior xcb:ConfigWindow:X
|
|
|
|
|
xcb:ConfigWindow:Width)
|
2023-06-09 02:00:00 +02:00
|
|
|
|
:x (- (slot-value workarea 'width) x)
|
2018-02-19 15:40:27 +01:00
|
|
|
|
:width x)))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(when map
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
2018-08-13 14:00:00 +02:00
|
|
|
|
(make-instance 'xcb:MapWindow
|
|
|
|
|
:window exwm-systemtray--embedder-window))))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(xcb:flush exwm-systemtray--connection))
|
|
|
|
|
|
2022-11-05 16:21:39 +01:00
|
|
|
|
(defun exwm-systemtray--refresh-background-color (&optional remap)
|
|
|
|
|
"Refresh background color after theme change or workspace switch.
|
|
|
|
|
If REMAP is not nil, map and unmap the embedder window so that the background is
|
|
|
|
|
redrawn."
|
2022-11-04 01:00:00 +01:00
|
|
|
|
;; Only `workspace-background' is dependent on current theme and workspace.
|
|
|
|
|
(when (eq 'workspace-background exwm-systemtray-background-color)
|
2022-11-05 16:21:39 +01:00
|
|
|
|
(exwm-systemtray--set-background-color)
|
|
|
|
|
(when remap
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:UnmapWindow
|
|
|
|
|
:window exwm-systemtray--embedder-window))
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:MapWindow
|
|
|
|
|
:window exwm-systemtray--embedder-window))
|
|
|
|
|
(xcb:flush exwm-systemtray--connection))))
|
2022-11-04 01:00:00 +01:00
|
|
|
|
|
2022-11-04 01:00:00 +01:00
|
|
|
|
(defun exwm-systemtray--set-background-color ()
|
|
|
|
|
"Change the background color of the embedder.
|
|
|
|
|
The color is set according to `exwm-systemtray-background-color'.
|
|
|
|
|
|
|
|
|
|
Note that this function does not change the current contents of the embedder
|
|
|
|
|
window; unmap & map are necessary for the background color to take effect."
|
|
|
|
|
(when (and exwm-systemtray--connection
|
|
|
|
|
exwm-systemtray--embedder-window)
|
|
|
|
|
(let* ((color (cl-case exwm-systemtray-background-color
|
|
|
|
|
((transparent nil) ; nil means transparent as well
|
|
|
|
|
(if (exwm-systemtray--transparency-supported-p)
|
|
|
|
|
nil
|
2022-11-04 01:00:00 +01:00
|
|
|
|
(message "%s" "[EXWM] system tray does not support \
|
|
|
|
|
`transparent' background; using `workspace-background' instead")
|
|
|
|
|
(face-background 'default exwm-workspace--current)))
|
|
|
|
|
(workspace-background
|
|
|
|
|
(face-background 'default exwm-workspace--current))
|
2022-11-04 01:00:00 +01:00
|
|
|
|
(t exwm-systemtray-background-color)))
|
|
|
|
|
(background-pixel (exwm--color->pixel color)))
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:ChangeWindowAttributes
|
|
|
|
|
:window exwm-systemtray--embedder-window
|
|
|
|
|
;; Either-or. A `background-pixel' of nil
|
|
|
|
|
;; means simulate transparency. We use
|
|
|
|
|
;; `xcb:CW:BackPixmap' together with
|
|
|
|
|
;; `xcb:BackPixmap:ParentRelative' do that,
|
|
|
|
|
;; but this only works when the parent
|
|
|
|
|
;; window's visual (Emacs') has the same
|
|
|
|
|
;; visual depth.
|
|
|
|
|
:value-mask (if background-pixel
|
|
|
|
|
xcb:CW:BackPixel
|
|
|
|
|
xcb:CW:BackPixmap)
|
|
|
|
|
;; Due to the :value-mask above,
|
|
|
|
|
;; :background-pixmap only takes effect when
|
|
|
|
|
;; `transparent' is requested and supported
|
|
|
|
|
;; (visual depth of Emacs and of system tray
|
|
|
|
|
;; are equal). Setting
|
|
|
|
|
;; `xcb:BackPixmap:ParentRelative' when
|
|
|
|
|
;; that's not the case would produce an
|
|
|
|
|
;; `xcb:Match' error.
|
|
|
|
|
:background-pixmap xcb:BackPixmap:ParentRelative
|
|
|
|
|
:background-pixel background-pixel)))))
|
|
|
|
|
|
|
|
|
|
(defun exwm-systemtray--transparency-supported-p ()
|
|
|
|
|
"Check whether transparent background is supported.
|
|
|
|
|
EXWM system tray supports transparency when the visual depth of the system tray
|
|
|
|
|
window matches that of Emacs. The visual depth of the system tray window is the
|
|
|
|
|
default visual depth of the display.
|
|
|
|
|
|
|
|
|
|
Sections \"Visual and background pixmap handling\" and
|
|
|
|
|
\"_NET_SYSTEM_TRAY_VISUAL\" of the System Tray Protocol Specification
|
|
|
|
|
\(https://specifications.freedesktop.org/systemtray-spec/systemtray-spec-latest.html#visuals)
|
|
|
|
|
indicate how to support actual transparency."
|
|
|
|
|
(let ((planes (x-display-planes)))
|
|
|
|
|
(if exwm-systemtray--embedder-window-depth
|
|
|
|
|
(= planes exwm-systemtray--embedder-window-depth)
|
|
|
|
|
(<= planes 24))))
|
|
|
|
|
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(defun exwm-systemtray--on-DestroyNotify (data _synthetic)
|
2023-08-18 02:00:00 +02:00
|
|
|
|
"Unembed icons on DestroyNotify.
|
|
|
|
|
Argument DATA contains the raw event data."
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(let ((obj (make-instance 'xcb:DestroyNotify)))
|
|
|
|
|
(xcb:unmarshal obj data)
|
|
|
|
|
(with-slots (window) obj
|
2016-02-19 10:12:43 +01:00
|
|
|
|
(when (assoc window exwm-systemtray--list)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(exwm-systemtray--unembed window)))))
|
|
|
|
|
|
|
|
|
|
(defun exwm-systemtray--on-ReparentNotify (data _synthetic)
|
2023-08-18 02:00:00 +02:00
|
|
|
|
"Unembed icons on ReparentNotify.
|
|
|
|
|
Argument DATA contains the raw event data."
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(let ((obj (make-instance 'xcb:ReparentNotify)))
|
|
|
|
|
(xcb:unmarshal obj data)
|
|
|
|
|
(with-slots (window parent) obj
|
2018-08-13 14:00:00 +02:00
|
|
|
|
(when (and (/= parent exwm-systemtray--embedder-window)
|
2016-02-19 10:12:43 +01:00
|
|
|
|
(assoc window exwm-systemtray--list))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(exwm-systemtray--unembed window)))))
|
|
|
|
|
|
|
|
|
|
(defun exwm-systemtray--on-ResizeRequest (data _synthetic)
|
2023-08-18 02:00:00 +02:00
|
|
|
|
"Resize the tray icon on ResizeRequest.
|
|
|
|
|
Argument DATA contains the raw event data."
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(let ((obj (make-instance 'xcb:ResizeRequest))
|
|
|
|
|
attr)
|
|
|
|
|
(xcb:unmarshal obj data)
|
|
|
|
|
(with-slots (window width height) obj
|
2016-02-19 10:12:43 +01:00
|
|
|
|
(when (setq attr (cdr (assoc window exwm-systemtray--list)))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(with-slots ((width* width)
|
|
|
|
|
(height* height))
|
|
|
|
|
attr
|
|
|
|
|
(setq height* exwm-systemtray-height
|
|
|
|
|
width* (round (* width (/ (float height*) height))))
|
|
|
|
|
(when (< width* exwm-systemtray--icon-min-size)
|
|
|
|
|
(setq width* exwm-systemtray--icon-min-size
|
|
|
|
|
height* (round (* height (/ (float width*) width)))))
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:ConfigureWindow
|
|
|
|
|
:window window
|
|
|
|
|
:value-mask (logior xcb:ConfigWindow:Y
|
|
|
|
|
xcb:ConfigWindow:Width
|
|
|
|
|
xcb:ConfigWindow:Height)
|
|
|
|
|
;; Vertically centered.
|
|
|
|
|
:y (/ (- exwm-systemtray-height height*) 2)
|
|
|
|
|
:width width*
|
|
|
|
|
:height height*)))
|
|
|
|
|
(exwm-systemtray--refresh)))))
|
|
|
|
|
|
|
|
|
|
(defun exwm-systemtray--on-PropertyNotify (data _synthetic)
|
2023-08-18 02:00:00 +02:00
|
|
|
|
"Map/Unmap the tray icon on PropertyNotify.
|
|
|
|
|
Argument DATA contains the raw event data."
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(let ((obj (make-instance 'xcb:PropertyNotify))
|
|
|
|
|
attr info visible)
|
|
|
|
|
(xcb:unmarshal obj data)
|
|
|
|
|
(with-slots (window atom state) obj
|
|
|
|
|
(when (and (eq state xcb:Property:NewValue)
|
|
|
|
|
(eq atom xcb:Atom:_XEMBED_INFO)
|
2016-02-19 10:12:43 +01:00
|
|
|
|
(setq attr (cdr (assoc window exwm-systemtray--list))))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(setq info (xcb:+request-unchecked+reply exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:xembed:get-_XEMBED_INFO
|
|
|
|
|
:window window)))
|
|
|
|
|
(when info
|
|
|
|
|
(setq visible (/= 0 (logand (slot-value info 'flags)
|
|
|
|
|
xcb:xembed:MAPPED)))
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log "#x%x visible? %s" window visible)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(if visible
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:MapWindow :window window))
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:UnmapWindow :window window)))
|
|
|
|
|
(setf (slot-value attr 'visible) visible)
|
|
|
|
|
(exwm-systemtray--refresh))))))
|
|
|
|
|
|
|
|
|
|
(defun exwm-systemtray--on-ClientMessage (data _synthetic)
|
2023-08-18 02:00:00 +02:00
|
|
|
|
"Handle client messages.
|
|
|
|
|
Argument DATA contains the raw event data."
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(let ((obj (make-instance 'xcb:ClientMessage))
|
|
|
|
|
opcode data32)
|
|
|
|
|
(xcb:unmarshal obj data)
|
|
|
|
|
(with-slots (window type data) obj
|
|
|
|
|
(when (eq type xcb:Atom:_NET_SYSTEM_TRAY_OPCODE)
|
|
|
|
|
(setq data32 (slot-value data 'data32)
|
|
|
|
|
opcode (elt data32 1))
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log "opcode: %s" opcode)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(cond ((= opcode xcb:systemtray:opcode:REQUEST-DOCK)
|
2016-02-19 13:18:29 +01:00
|
|
|
|
(unless (assoc (elt data32 2) exwm-systemtray--list)
|
|
|
|
|
(exwm-systemtray--embed (elt data32 2))))
|
|
|
|
|
;; Not implemented (rarely used nowadays).
|
|
|
|
|
((or (= opcode xcb:systemtray:opcode:BEGIN-MESSAGE)
|
|
|
|
|
(= opcode xcb:systemtray:opcode:CANCEL-MESSAGE)))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(t
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log "Unknown opcode message: %s" obj)))))))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
|
2016-09-23 12:29:11 +02:00
|
|
|
|
(defun exwm-systemtray--on-KeyPress (data _synthetic)
|
2023-08-18 02:00:00 +02:00
|
|
|
|
"Forward all KeyPress events to Emacs frame.
|
|
|
|
|
Argument DATA contains the raw event data."
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log)
|
2016-09-23 12:29:11 +02:00
|
|
|
|
;; This function is only executed when there's no autohide minibuffer,
|
|
|
|
|
;; a workspace frame has the input focus and the pointer is over a
|
|
|
|
|
;; tray icon.
|
|
|
|
|
(let ((dest (frame-parameter (selected-frame) 'exwm-outer-id))
|
|
|
|
|
(obj (make-instance 'xcb:KeyPress)))
|
|
|
|
|
(xcb:unmarshal obj data)
|
|
|
|
|
(setf (slot-value obj 'event) dest)
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:SendEvent
|
|
|
|
|
:propagate 0
|
|
|
|
|
:destination dest
|
|
|
|
|
:event-mask xcb:EventMask:NoEvent
|
|
|
|
|
:event (xcb:marshal obj exwm-systemtray--connection))))
|
|
|
|
|
(xcb:flush exwm-systemtray--connection))
|
|
|
|
|
|
2016-02-19 10:12:43 +01:00
|
|
|
|
(defun exwm-systemtray--on-workspace-switch ()
|
|
|
|
|
"Reparent/Refresh the system tray in `exwm-workspace-switch-hook'."
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log)
|
2016-02-21 13:19:45 +01:00
|
|
|
|
(unless (exwm-workspace--minibuffer-own-frame-p)
|
2019-09-14 02:00:00 +02:00
|
|
|
|
(exwm-workspace--update-offsets)
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:ReparentWindow
|
|
|
|
|
:window exwm-systemtray--embedder-window
|
|
|
|
|
:parent (string-to-number
|
|
|
|
|
(frame-parameter exwm-workspace--current
|
|
|
|
|
'window-id))
|
|
|
|
|
:x 0
|
2023-06-09 02:00:00 +02:00
|
|
|
|
:y (- (slot-value (exwm-workspace--workarea
|
|
|
|
|
exwm-workspace-current-index)
|
|
|
|
|
'height)
|
2019-09-14 02:00:00 +02:00
|
|
|
|
exwm-workspace--frame-y-offset
|
|
|
|
|
exwm-systemtray-height))))
|
2022-11-04 01:00:00 +01:00
|
|
|
|
(exwm-systemtray--refresh-background-color)
|
2016-02-19 10:12:43 +01:00
|
|
|
|
(exwm-systemtray--refresh))
|
|
|
|
|
|
2022-11-05 16:21:05 +01:00
|
|
|
|
(defun exwm-systemtray--on-theme-change (_theme)
|
2022-11-04 01:00:00 +01:00
|
|
|
|
"Refresh system tray upon theme change."
|
2022-11-05 16:21:39 +01:00
|
|
|
|
(exwm-systemtray--refresh-background-color 'remap))
|
2022-11-04 01:00:00 +01:00
|
|
|
|
|
2019-09-14 02:00:00 +02:00
|
|
|
|
(defun exwm-systemtray--refresh-all ()
|
|
|
|
|
"Reposition/Refresh the system tray."
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log)
|
2016-02-21 13:19:45 +01:00
|
|
|
|
(unless (exwm-workspace--minibuffer-own-frame-p)
|
2019-09-14 02:00:00 +02:00
|
|
|
|
(exwm-workspace--update-offsets)
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:ConfigureWindow
|
|
|
|
|
:window exwm-systemtray--embedder-window
|
|
|
|
|
:value-mask xcb:ConfigWindow:Y
|
2023-06-09 02:00:00 +02:00
|
|
|
|
:y (- (slot-value (exwm-workspace--workarea
|
|
|
|
|
exwm-workspace-current-index)
|
|
|
|
|
'height)
|
2019-09-14 02:00:00 +02:00
|
|
|
|
exwm-workspace--frame-y-offset
|
|
|
|
|
exwm-systemtray-height))))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(exwm-systemtray--refresh))
|
|
|
|
|
|
2016-07-14 16:08:27 +02:00
|
|
|
|
(cl-defun exwm-systemtray--init ()
|
2016-02-19 04:02:37 +01:00
|
|
|
|
"Initialize system tray module."
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(cl-assert (not exwm-systemtray--connection))
|
|
|
|
|
(cl-assert (not exwm-systemtray--list))
|
|
|
|
|
(cl-assert (not exwm-systemtray--selection-owner-window))
|
2018-08-13 14:00:00 +02:00
|
|
|
|
(cl-assert (not exwm-systemtray--embedder-window))
|
2016-02-21 13:19:45 +01:00
|
|
|
|
(unless exwm-systemtray-height
|
|
|
|
|
(setq exwm-systemtray-height (max exwm-systemtray--icon-min-size
|
2022-08-07 00:01:40 +02:00
|
|
|
|
(with-selected-window (minibuffer-window)
|
|
|
|
|
(line-pixel-height)))))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
;; Create a new connection.
|
2016-05-12 18:11:12 +02:00
|
|
|
|
(setq exwm-systemtray--connection (xcb:connect))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(set-process-query-on-exit-flag (slot-value exwm-systemtray--connection
|
|
|
|
|
'process)
|
|
|
|
|
nil)
|
|
|
|
|
;; Initialize XELB modules.
|
2016-05-23 13:13:42 +02:00
|
|
|
|
(xcb:xembed:init exwm-systemtray--connection t)
|
|
|
|
|
(xcb:systemtray:init exwm-systemtray--connection t)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
;; Acquire the manager selection _NET_SYSTEM_TRAY_S0.
|
|
|
|
|
(with-slots (owner)
|
|
|
|
|
(xcb:+request-unchecked+reply exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:GetSelectionOwner
|
|
|
|
|
:selection xcb:Atom:_NET_SYSTEM_TRAY_S0))
|
|
|
|
|
(when (/= owner xcb:Window:None)
|
2016-07-14 16:08:27 +02:00
|
|
|
|
(xcb:disconnect exwm-systemtray--connection)
|
2018-03-08 18:06:39 +01:00
|
|
|
|
(setq exwm-systemtray--connection nil)
|
2016-07-14 16:08:27 +02:00
|
|
|
|
(warn "[EXWM] Other system tray detected")
|
|
|
|
|
(cl-return-from exwm-systemtray--init)))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(let ((id (xcb:generate-id exwm-systemtray--connection)))
|
|
|
|
|
(setq exwm-systemtray--selection-owner-window id)
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:CreateWindow
|
2016-08-12 13:18:32 +02:00
|
|
|
|
:depth 0
|
|
|
|
|
:wid id
|
|
|
|
|
:parent exwm--root
|
|
|
|
|
:x 0
|
|
|
|
|
:y 0
|
|
|
|
|
:width 1
|
|
|
|
|
:height 1
|
|
|
|
|
:border-width 0
|
|
|
|
|
:class xcb:WindowClass:InputOnly
|
|
|
|
|
:visual 0
|
|
|
|
|
:value-mask xcb:CW:OverrideRedirect
|
2016-02-19 04:02:37 +01:00
|
|
|
|
:override-redirect 1))
|
|
|
|
|
;; Get the selection ownership.
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:SetSelectionOwner
|
|
|
|
|
:owner id
|
|
|
|
|
:selection xcb:Atom:_NET_SYSTEM_TRAY_S0
|
|
|
|
|
:time xcb:Time:CurrentTime))
|
2016-04-21 15:37:02 +02:00
|
|
|
|
;; Send a client message to announce the selection.
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:SendEvent
|
|
|
|
|
:propagate 0
|
|
|
|
|
:destination exwm--root
|
|
|
|
|
:event-mask xcb:EventMask:StructureNotify
|
|
|
|
|
:event (xcb:marshal
|
|
|
|
|
(make-instance 'xcb:systemtray:-ClientMessage
|
|
|
|
|
:window exwm--root
|
|
|
|
|
:time xcb:Time:CurrentTime
|
|
|
|
|
:selection
|
|
|
|
|
xcb:Atom:_NET_SYSTEM_TRAY_S0
|
|
|
|
|
:owner id)
|
|
|
|
|
exwm-systemtray--connection)))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
;; Set _NET_WM_NAME.
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:ewmh:set-_NET_WM_NAME
|
2018-08-13 14:00:00 +02:00
|
|
|
|
:window id
|
|
|
|
|
:data "EXWM: exwm-systemtray--selection-owner-window"))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
;; Set the _NET_SYSTEM_TRAY_ORIENTATION property.
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:xembed:set-_NET_SYSTEM_TRAY_ORIENTATION
|
|
|
|
|
:window id
|
|
|
|
|
:data xcb:systemtray:ORIENTATION:HORZ)))
|
|
|
|
|
;; Create the embedder.
|
|
|
|
|
(let ((id (xcb:generate-id exwm-systemtray--connection))
|
2022-11-04 01:00:00 +01:00
|
|
|
|
frame parent embedder-depth embedder-visual embedder-colormap y)
|
2018-08-13 14:00:00 +02:00
|
|
|
|
(setq exwm-systemtray--embedder-window id)
|
2016-02-21 13:19:45 +01:00
|
|
|
|
(if (exwm-workspace--minibuffer-own-frame-p)
|
2016-08-07 07:34:50 +02:00
|
|
|
|
(setq frame exwm-workspace--minibuffer
|
|
|
|
|
y (if (>= (line-pixel-height) exwm-systemtray-height)
|
|
|
|
|
;; Bottom aligned.
|
|
|
|
|
(- (line-pixel-height) exwm-systemtray-height)
|
|
|
|
|
;; Vertically centered.
|
|
|
|
|
(/ (- (line-pixel-height) exwm-systemtray-height) 2)))
|
2019-09-14 02:00:00 +02:00
|
|
|
|
(exwm-workspace--update-offsets)
|
|
|
|
|
(setq frame exwm-workspace--current
|
|
|
|
|
;; Bottom aligned.
|
2023-06-09 02:00:00 +02:00
|
|
|
|
y (- (slot-value (exwm-workspace--workarea
|
|
|
|
|
exwm-workspace-current-index)
|
|
|
|
|
'height)
|
2019-09-14 02:00:00 +02:00
|
|
|
|
exwm-workspace--frame-y-offset
|
|
|
|
|
exwm-systemtray-height)))
|
2022-11-04 01:00:00 +01:00
|
|
|
|
(setq parent (string-to-number (frame-parameter frame 'window-id)))
|
|
|
|
|
;; Use default depth, visual and colormap (from root window), instead of
|
|
|
|
|
;; Emacs frame's. See Section "Visual and background pixmap handling" in
|
|
|
|
|
;; "System Tray Protocol Specification 0.3".
|
|
|
|
|
(let* ((vdc (exwm--get-visual-depth-colormap exwm-systemtray--connection
|
|
|
|
|
exwm--root)))
|
|
|
|
|
(setq embedder-visual (car vdc))
|
|
|
|
|
(setq embedder-depth (cadr vdc))
|
|
|
|
|
(setq embedder-colormap (caddr vdc)))
|
|
|
|
|
;; Note down the embedder window's depth. It will be used to check whether
|
|
|
|
|
;; we can use xcb:BackPixmap:ParentRelative to emulate transparency.
|
|
|
|
|
(setq exwm-systemtray--embedder-window-depth embedder-depth)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
2016-08-07 07:34:50 +02:00
|
|
|
|
(make-instance 'xcb:CreateWindow
|
2022-11-04 01:00:00 +01:00
|
|
|
|
:depth embedder-depth
|
2016-08-07 07:34:50 +02:00
|
|
|
|
:wid id
|
|
|
|
|
:parent parent
|
|
|
|
|
:x 0
|
|
|
|
|
:y y
|
|
|
|
|
:width 1
|
|
|
|
|
:height exwm-systemtray-height
|
|
|
|
|
:border-width 0
|
2016-08-12 13:18:32 +02:00
|
|
|
|
:class xcb:WindowClass:InputOutput
|
2022-11-04 01:00:00 +01:00
|
|
|
|
:visual embedder-visual
|
|
|
|
|
:colormap embedder-colormap
|
|
|
|
|
:value-mask (logior xcb:CW:BorderPixel
|
|
|
|
|
xcb:CW:Colormap
|
2020-02-02 01:00:00 +01:00
|
|
|
|
xcb:CW:EventMask)
|
2022-11-04 01:00:00 +01:00
|
|
|
|
:border-pixel 0
|
2016-08-07 07:34:50 +02:00
|
|
|
|
:event-mask xcb:EventMask:SubstructureNotify))
|
2022-11-04 01:00:00 +01:00
|
|
|
|
(exwm-systemtray--set-background-color)
|
2016-02-19 04:02:37 +01:00
|
|
|
|
;; Set _NET_WM_NAME.
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:ewmh:set-_NET_WM_NAME
|
2018-08-13 14:00:00 +02:00
|
|
|
|
:window id
|
2022-11-04 01:00:00 +01:00
|
|
|
|
:data "EXWM: exwm-systemtray--embedder-window"))
|
2022-11-04 01:00:00 +01:00
|
|
|
|
;; Set _NET_WM_WINDOW_TYPE.
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:ewmh:set-_NET_WM_WINDOW_TYPE
|
|
|
|
|
:window id
|
|
|
|
|
:data (vector xcb:Atom:_NET_WM_WINDOW_TYPE_DOCK)))
|
2022-11-04 01:00:00 +01:00
|
|
|
|
;; Set _NET_SYSTEM_TRAY_VISUAL.
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:xembed:set-_NET_SYSTEM_TRAY_VISUAL
|
|
|
|
|
:window exwm-systemtray--selection-owner-window
|
|
|
|
|
:data embedder-visual)))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
(xcb:flush exwm-systemtray--connection)
|
|
|
|
|
;; Attach event listeners.
|
|
|
|
|
(xcb:+event exwm-systemtray--connection 'xcb:DestroyNotify
|
|
|
|
|
#'exwm-systemtray--on-DestroyNotify)
|
|
|
|
|
(xcb:+event exwm-systemtray--connection 'xcb:ReparentNotify
|
|
|
|
|
#'exwm-systemtray--on-ReparentNotify)
|
|
|
|
|
(xcb:+event exwm-systemtray--connection 'xcb:ResizeRequest
|
|
|
|
|
#'exwm-systemtray--on-ResizeRequest)
|
|
|
|
|
(xcb:+event exwm-systemtray--connection 'xcb:PropertyNotify
|
|
|
|
|
#'exwm-systemtray--on-PropertyNotify)
|
|
|
|
|
(xcb:+event exwm-systemtray--connection 'xcb:ClientMessage
|
|
|
|
|
#'exwm-systemtray--on-ClientMessage)
|
2016-09-23 12:29:11 +02:00
|
|
|
|
(unless (exwm-workspace--minibuffer-own-frame-p)
|
|
|
|
|
(xcb:+event exwm-systemtray--connection 'xcb:KeyPress
|
|
|
|
|
#'exwm-systemtray--on-KeyPress))
|
2016-02-19 10:12:43 +01:00
|
|
|
|
;; Add hook to move/reparent the embedder.
|
|
|
|
|
(add-hook 'exwm-workspace-switch-hook #'exwm-systemtray--on-workspace-switch)
|
2017-02-24 16:05:43 +01:00
|
|
|
|
(add-hook 'exwm-workspace--update-workareas-hook
|
2019-09-14 02:00:00 +02:00
|
|
|
|
#'exwm-systemtray--refresh-all)
|
2022-11-04 01:00:00 +01:00
|
|
|
|
;; Add hook to update background colors.
|
|
|
|
|
(add-hook 'enable-theme-functions #'exwm-systemtray--on-theme-change)
|
|
|
|
|
(add-hook 'disable-theme-functions #'exwm-systemtray--on-theme-change)
|
2019-09-14 02:00:00 +02:00
|
|
|
|
(add-hook 'menu-bar-mode-hook #'exwm-systemtray--refresh-all)
|
|
|
|
|
(add-hook 'tool-bar-mode-hook #'exwm-systemtray--refresh-all)
|
2016-05-23 13:13:42 +02:00
|
|
|
|
(when (boundp 'exwm-randr-refresh-hook)
|
2019-09-14 02:00:00 +02:00
|
|
|
|
(add-hook 'exwm-randr-refresh-hook #'exwm-systemtray--refresh-all))
|
2017-08-30 19:00:51 +02:00
|
|
|
|
;; The struts can be updated already.
|
|
|
|
|
(when exwm-workspace--workareas
|
2019-09-14 02:00:00 +02:00
|
|
|
|
(exwm-systemtray--refresh-all)))
|
2016-05-23 13:13:42 +02:00
|
|
|
|
|
|
|
|
|
(defun exwm-systemtray--exit ()
|
|
|
|
|
"Exit the systemtray module."
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log)
|
2016-05-23 13:13:42 +02:00
|
|
|
|
(when exwm-systemtray--connection
|
2023-06-09 02:00:00 +02:00
|
|
|
|
(when (slot-value exwm-systemtray--connection 'connected)
|
|
|
|
|
;; Hide & reparent out the embedder before disconnection to prevent
|
|
|
|
|
;; embedded icons from being reparented to an Emacs frame (which is the
|
|
|
|
|
;; parent of the embedder).
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:UnmapWindow
|
|
|
|
|
:window exwm-systemtray--embedder-window))
|
|
|
|
|
(xcb:+request exwm-systemtray--connection
|
|
|
|
|
(make-instance 'xcb:ReparentWindow
|
|
|
|
|
:window exwm-systemtray--embedder-window
|
|
|
|
|
:parent exwm--root
|
|
|
|
|
:x 0
|
|
|
|
|
:y 0))
|
|
|
|
|
(xcb:disconnect exwm-systemtray--connection))
|
2016-05-23 13:13:42 +02:00
|
|
|
|
(setq exwm-systemtray--connection nil
|
|
|
|
|
exwm-systemtray--list nil
|
|
|
|
|
exwm-systemtray--selection-owner-window nil
|
2022-11-04 01:00:00 +01:00
|
|
|
|
exwm-systemtray--embedder-window nil
|
|
|
|
|
exwm-systemtray--embedder-window-depth nil)
|
2016-05-23 13:13:42 +02:00
|
|
|
|
(remove-hook 'exwm-workspace-switch-hook
|
|
|
|
|
#'exwm-systemtray--on-workspace-switch)
|
2017-02-24 16:05:43 +01:00
|
|
|
|
(remove-hook 'exwm-workspace--update-workareas-hook
|
2019-09-14 02:00:00 +02:00
|
|
|
|
#'exwm-systemtray--refresh-all)
|
2022-11-04 01:00:00 +01:00
|
|
|
|
(remove-hook 'enable-theme-functions #'exwm-systemtray--on-theme-change)
|
|
|
|
|
(remove-hook 'disable-theme-functions #'exwm-systemtray--on-theme-change)
|
2019-09-14 02:00:00 +02:00
|
|
|
|
(remove-hook 'menu-bar-mode-hook #'exwm-systemtray--refresh-all)
|
|
|
|
|
(remove-hook 'tool-bar-mode-hook #'exwm-systemtray--refresh-all)
|
2016-05-23 13:13:42 +02:00
|
|
|
|
(when (boundp 'exwm-randr-refresh-hook)
|
2019-09-14 02:00:00 +02:00
|
|
|
|
(remove-hook 'exwm-randr-refresh-hook #'exwm-systemtray--refresh-all))))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
|
|
|
|
|
(defun exwm-systemtray-enable ()
|
|
|
|
|
"Enable system tray support for EXWM."
|
2018-12-02 01:00:00 +01:00
|
|
|
|
(exwm--log)
|
2016-05-23 13:13:42 +02:00
|
|
|
|
(add-hook 'exwm-init-hook #'exwm-systemtray--init)
|
|
|
|
|
(add-hook 'exwm-exit-hook #'exwm-systemtray--exit))
|
2016-02-19 04:02:37 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(provide 'exwm-systemtray)
|
|
|
|
|
|
2017-02-05 10:50:52 +01:00
|
|
|
|
;;; exwm-systemtray.el ends here
|