From: martin rudalics <rudalics@gmx.at>
To: Dmitry Gutov <dgutov@yandex.ru>, tumashu <tumashu@163.com>
Cc: "emacs-devel@gnu.org" <emacs-devel@gnu.org>
Subject: Re: Emacs's set-frame-size can not work well with gnome-shell?
Date: Fri, 13 Mar 2020 18:46:19 +0100 [thread overview]
Message-ID: <5b27dc36-df18-d188-eab3-8bf546a8c24a@gmx.at> (raw)
In-Reply-To: <384dd180-b194-d2b7-0a2b-2725bf2a1360@yandex.ru>
[-- Attachment #1: Type: text/plain, Size: 1560 bytes --]
> With a custom var, you mean. OK.
I attach the latest diff I made for Emacs 27. The variable is called
'x-gtk-resize-child-frames' and may assume the values 'hide' and
'resize-mode' in addition to the default nil. It should work for Emacs
28 as well but it would be important to test it on Emacs 27 for obvious
reasons.
Clearly, people might want to to set 'x-wait-for-event-timeout' to zero
as well and we should tell them so. But here I can't observe that doing
so has any impact.
> IIUC though, the majority of the GTK developers work on GNOME and
> Mutter as well. If that's the case, asking for Mutter's developers'
> help makes sense anyway.
It would make sense but if they don't respond ...
> I asked that question today. Got one +1 so far: https://github.com/tumashu/company-posframe/issues/2#issuecomment-598809266
Not much so far. In either case, whenever people report a "it changes
size somewhat half a second later" then this usually means that a frame
move occurred on a platform (like GNOME shell) that does not report a
frame position as Emacs expects it (Bug#38452), does not send a suitable
event in due time and is thereafter penalized by xterm.c's
/* As a last resort, just wait 0.5 seconds and hope that XGetGeometry
will then return up-to-date position info. */
wait_reading_process_output (0, 500000000, 0, false, Qnil, NULL, 0);
This should be bypassed by my patch but for non-child frames the delay
persists. Users then might want to drop a couple of zeros from that
insane nanosecond argument.
martin
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: x-gtk-resize-child-frames.diff --]
[-- Type: text/x-patch; name="x-gtk-resize-child-frames.diff", Size: 40850 bytes --]
diff --git a/lisp/mouse.el b/lisp/mouse.el
index e58a2e6da1..9703d957d5 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -552,7 +552,7 @@ mouse-drag-mode-line
(not (eq (window-frame minibuffer-window) frame))))
;; Drag frame when the window is on the bottom of its frame and
;; there is no minibuffer window below.
- (mouse-drag-frame start-event 'move)))))
+ (mouse-drag-frame-move start-event)))))
(defun mouse-drag-header-line (start-event)
"Change the height of a window by dragging on its header line.
@@ -569,7 +569,7 @@ mouse-drag-header-line
(mouse-drag-line start-event 'header)
(let ((frame (window-frame window)))
(when (frame-parameter frame 'drag-with-header-line)
- (mouse-drag-frame start-event 'move))))))
+ (mouse-drag-frame-move start-event))))))
(defun mouse-drag-vertical-line (start-event)
"Change the width of a window by dragging on a vertical line.
@@ -577,46 +577,7 @@ mouse-drag-vertical-line
(interactive "e")
(mouse-drag-line start-event 'vertical))
\f
-(defun mouse-resize-frame (frame x-diff y-diff &optional x-move y-move)
- "Helper function for `mouse-drag-frame'."
- (let* ((frame-x-y (frame-position frame))
- (frame-x (car frame-x-y))
- (frame-y (cdr frame-x-y))
- alist)
- (if (> x-diff 0)
- (when x-move
- (setq x-diff (min x-diff frame-x))
- (setq x-move (- frame-x x-diff)))
- (let* ((min-width (frame-windows-min-size frame t nil t))
- (min-diff (max 0 (- (frame-inner-width frame) min-width))))
- (setq x-diff (max x-diff (- min-diff)))
- (when x-move
- (setq x-move (+ frame-x (- x-diff))))))
-
- (if (> y-diff 0)
- (when y-move
- (setq y-diff (min y-diff frame-y))
- (setq y-move (- frame-y y-diff)))
- (let* ((min-height (frame-windows-min-size frame nil nil t))
- (min-diff (max 0 (- (frame-inner-height frame) min-height))))
- (setq y-diff (max y-diff (- min-diff)))
- (when y-move
- (setq y-move (+ frame-y (- y-diff))))))
-
- (unless (zerop x-diff)
- (when x-move
- (push `(left . ,x-move) alist))
- (push `(width . (text-pixels . ,(+ (frame-text-width frame) x-diff)))
- alist))
- (unless (zerop y-diff)
- (when y-move
- (push `(top . ,y-move) alist))
- (push `(height . (text-pixels . ,(+ (frame-text-height frame) y-diff)))
- alist))
- (when alist
- (modify-frame-parameters frame alist))))
-
-(defun mouse-drag-frame (start-event part)
+(defun mouse-drag-frame-resize (start-event part)
"Drag a frame or one of its edges with the mouse.
START-EVENT is the starting mouse event of the drag action. Its
position window denotes the frame that will be dragged.
@@ -635,9 +596,144 @@ mouse-drag-frame
(frame (if (window-live-p window)
(window-frame window)
window))
- (width (frame-native-width frame))
- (height (frame-native-height frame))
- ;; PARENT is the parent frame of FRAME or, if FRAME is a
+ ;; Initial "first" frame position and size. While dragging we
+ ;; base all calculations against that size and position.
+ (first-pos (frame-position frame))
+ (first-left (car first-pos))
+ (first-top (cdr first-pos))
+ (first-width (frame-text-width frame))
+ (first-height (frame-text-height frame))
+ ;; Don't let FRAME become less large than the size needed to
+ ;; fit all of its windows.
+ (min-text-width
+ (+ (frame-windows-min-size frame t nil t)
+ (- (frame-inner-width frame) first-width)))
+ (min-text-height
+ (+ (frame-windows-min-size frame nil nil t)
+ (- (frame-inner-height frame) first-height)))
+ ;; PARENT is the parent frame of FRAME or, if FRAME is a
+ ;; top-level frame, FRAME's workarea.
+ (parent (frame-parent frame))
+ (parent-edges
+ (if parent
+ (frame-edges parent)
+ (let* ((attributes
+ (car (display-monitor-attributes-list)))
+ (workarea (assq 'workarea attributes)))
+ (and workarea
+ `(,(nth 1 workarea) ,(nth 2 workarea)
+ ,(+ (nth 1 workarea) (nth 3 workarea))
+ ,(+ (nth 2 workarea) (nth 4 workarea)))))))
+ (parent-left (and parent-edges (nth 0 parent-edges)))
+ (parent-top (and parent-edges (nth 1 parent-edges)))
+ (parent-right (and parent-edges (nth 2 parent-edges)))
+ (parent-bottom (and parent-edges (nth 3 parent-edges)))
+ ;; Drag types. drag-left/drag-right and drag-top/drag-bottom
+ ;; are mutually exclusive.
+ (drag-left (memq part '(bottom-left left top-left)))
+ (drag-top (memq part '(top-left top top-right)))
+ (drag-right (memq part '(top-right right bottom-right)))
+ (drag-bottom (memq part '(bottom-right bottom bottom-left)))
+ ;; Initial "first" mouse position. While dragging we base all
+ ;; calculations against that position.
+ (first-x-y (mouse-absolute-pixel-position))
+ (first-x (car first-x-y))
+ (first-y (cdr first-x-y))
+ (exitfun nil)
+ (move
+ (lambda (event)
+ (interactive "e")
+ (when (consp event)
+ (let* ((last-x-y (mouse-absolute-pixel-position))
+ (last-x (car last-x-y))
+ (last-y (cdr last-x-y))
+ (left (- last-x first-x))
+ (top (- last-y first-y))
+ alist)
+ ;; We never want to warp the mouse position here. When
+ ;; moving the mouse leftward or upward, then with a wide
+ ;; border the calculated left or top position of the
+ ;; frame could drop to a value less than zero depending
+ ;; on where precisely the mouse within the border. We
+ ;; guard against this by never allowing the frame to
+ ;; move to a position less than zero here. No such
+ ;; precautions are used for the right and bottom borders
+ ;; so with a large internal border parts of that border
+ ;; may disappear.
+ (when (and drag-left (>= last-x parent-left)
+ (>= (- first-width left) min-text-width))
+ (push `(left . ,(max (+ first-left left) 0)) alist)
+ (push `(width . (text-pixels . ,(- first-width left)))
+ alist))
+ (when (and drag-top (>= last-y parent-top)
+ (>= (- first-height top) min-text-height))
+ (push `(top . ,(max 0 (+ first-top top))) alist)
+ (push `(height . (text-pixels . ,(- first-height top)))
+ alist))
+ (when (and drag-right (<= last-x parent-right)
+ (>= (+ first-width left) min-text-width))
+ (push `(width . (text-pixels . ,(+ first-width left)))
+ alist))
+ (when (and drag-bottom (<= last-y parent-bottom)
+ (>= (+ first-height top) min-text-height))
+ (push `(height . (text-pixels . ,(+ first-height top)))
+ alist))
+ (modify-frame-parameters frame alist)))))
+ (old-track-mouse track-mouse))
+ ;; Start tracking. The special value 'dragging' signals the
+ ;; display engine to freeze the mouse pointer shape for as long
+ ;; as we drag.
+ (setq track-mouse 'dragging)
+ ;; Loop reading events and sampling the position of the mouse.
+ (setq exitfun
+ (set-transient-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [switch-frame] #'ignore)
+ (define-key map [select-window] #'ignore)
+ (define-key map [scroll-bar-movement] #'ignore)
+ (define-key map [mouse-movement] move)
+ ;; Swallow drag-mouse-1 events to avoid selecting some other window.
+ (define-key map [drag-mouse-1]
+ (lambda () (interactive) (funcall exitfun)))
+ ;; Some of the events will of course end up looked up
+ ;; with a mode-line, header-line or vertical-line prefix ...
+ (define-key map [mode-line] map)
+ (define-key map [header-line] map)
+ (define-key map [vertical-line] map)
+ ;; ... and some maybe even with a right- or bottom-divider
+ ;; prefix.
+ (define-key map [right-divider] map)
+ (define-key map [bottom-divider] map)
+ map)
+ t (lambda () (setq track-mouse old-track-mouse))))))
+
+(defun mouse-drag-frame-move (start-event)
+ "Drag a frame or one of its edges with the mouse.
+START-EVENT is the starting mouse event of the drag action. Its
+position window denotes the frame that will be dragged.
+
+PART specifies the part that has been dragged and must be one of
+the symbols `left', `top', `right', `bottom', `top-left',
+`top-right', `bottom-left', `bottom-right' to drag an internal
+border or edge. If PART equals `move', this means to move the
+frame with the mouse."
+ ;; Give temporary modes such as isearch a chance to turn off.
+ (run-hooks 'mouse-leave-buffer-hook)
+ (let* ((echo-keystrokes 0)
+ (start (event-start start-event))
+ (window (posn-window start))
+ ;; FRAME is the frame to drag.
+ (frame (if (window-live-p window)
+ (window-frame window)
+ window))
+ (native-width (frame-native-width frame))
+ (native-height (frame-native-height frame))
+ ;; Initial "first" frame position and size. While dragging we
+ ;; base all calculations against that size and position.
+ (first-pos (frame-position frame))
+ (first-left (car first-pos))
+ (first-top (cdr first-pos))
+ ;; PARENT is the parent frame of FRAME or, if FRAME is a
;; top-level frame, FRAME's workarea.
(parent (frame-parent frame))
(parent-edges
@@ -654,19 +750,16 @@ mouse-drag-frame
(parent-top (and parent-edges (nth 1 parent-edges)))
(parent-right (and parent-edges (nth 2 parent-edges)))
(parent-bottom (and parent-edges (nth 3 parent-edges)))
- ;; `pos-x' and `pos-y' record the x- and y-coordinates of the
- ;; last sampled mouse position. Note that we sample absolute
- ;; mouse positions to avoid that moving the mouse from one
- ;; frame into another gets into our way. `last-x' and `last-y'
- ;; records the x- and y-coordinates of the previously sampled
- ;; position. The differences between `last-x' and `pos-x' as
- ;; well as `last-y' and `pos-y' determine the amount the mouse
- ;; has been dragged between the last two samples.
- pos-x-y pos-x pos-y
- (last-x-y (mouse-absolute-pixel-position))
- (last-x (car last-x-y))
- (last-y (cdr last-x-y))
- ;; `snap-x' and `snap-y' record the x- and y-coordinates of the
+ ;; Initial "first" mouse position. While dragging we base all
+ ;; calculations against that position.
+ (first-x-y (mouse-absolute-pixel-position))
+ (first-x (car first-x-y))
+ (first-y (cdr first-x-y))
+ ;; `snap-width' (maybe also a yet to be provided `snap-height')
+ ;; could become floats to handle proportionality wrt PARENT.
+ ;; We don't do any checks on this parameter so far.
+ (snap-width (frame-parameter frame 'snap-width))
+ ;; `snap-x' and `snap-y' record the x- and y-coordinates of the
;; mouse position when FRAME snapped. As soon as the
;; difference between `pos-x' and `snap-x' (or `pos-y' and
;; `snap-y') exceeds the value of FRAME's `snap-width'
@@ -678,176 +771,141 @@ mouse-drag-frame
(lambda (event)
(interactive "e")
(when (consp event)
- (setq pos-x-y (mouse-absolute-pixel-position))
- (setq pos-x (car pos-x-y))
- (setq pos-y (cdr pos-x-y))
- (cond
- ((eq part 'left)
- (mouse-resize-frame frame (- last-x pos-x) 0 t))
- ((eq part 'top)
- (mouse-resize-frame frame 0 (- last-y pos-y) nil t))
- ((eq part 'right)
- (mouse-resize-frame frame (- pos-x last-x) 0))
- ((eq part 'bottom)
- (mouse-resize-frame frame 0 (- pos-y last-y)))
- ((eq part 'top-left)
- (mouse-resize-frame
- frame (- last-x pos-x) (- last-y pos-y) t t))
- ((eq part 'top-right)
- (mouse-resize-frame
- frame (- pos-x last-x) (- last-y pos-y) nil t))
- ((eq part 'bottom-left)
- (mouse-resize-frame
- frame (- last-x pos-x) (- pos-y last-y) t))
- ((eq part 'bottom-right)
- (mouse-resize-frame
- frame (- pos-x last-x) (- pos-y last-y)))
- ((eq part 'move)
- (let* ((old-position (frame-position frame))
- (old-left (car old-position))
- (old-top (cdr old-position))
- (left (+ old-left (- pos-x last-x)))
- (top (+ old-top (- pos-y last-y)))
- right bottom
- ;; `snap-width' (maybe also a yet to be provided
- ;; `snap-height') could become floats to handle
- ;; proportionality wrt PARENT. We don't do any
- ;; checks on this parameter so far.
- (snap-width (frame-parameter frame 'snap-width)))
- ;; Docking and constraining.
- (when (and (numberp snap-width) parent-edges)
+ (let* ((last-x-y (mouse-absolute-pixel-position))
+ (last-x (car last-x-y))
+ (last-y (cdr last-x-y))
+ (left (- last-x first-x))
+ (top (- last-y first-y))
+ right bottom)
+ (setq left (+ first-left left))
+ (setq top (+ first-top top))
+ ;; Docking and constraining.
+ (when (and (numberp snap-width) parent-edges)
+ (cond
+ ;; Docking at the left parent edge.
+ ((< last-x first-x)
(cond
- ;; Docking at the left parent edge.
- ((< pos-x last-x)
- (cond
- ((and (> left parent-left)
- (<= (- left parent-left) snap-width))
- ;; Snap when the mouse moved leftward and
- ;; FRAME's left edge would end up within
- ;; `snap-width' pixels from PARENT's left edge.
- (setq snap-x pos-x)
- (setq left parent-left))
- ((and (<= left parent-left)
- (<= (- parent-left left) snap-width)
- snap-x (<= (- snap-x pos-x) snap-width))
- ;; Stay snapped when the mouse moved leftward
- ;; but not more than `snap-width' pixels from
- ;; the time FRAME snapped.
- (setq left parent-left))
- (t
- ;; Unsnap when the mouse moved more than
- ;; `snap-width' pixels leftward from the time
- ;; FRAME snapped.
- (setq snap-x nil))))
- ((> pos-x last-x)
- (setq right (+ left width))
- (cond
- ((and (< right parent-right)
- (<= (- parent-right right) snap-width))
- ;; Snap when the mouse moved rightward and
- ;; FRAME's right edge would end up within
- ;; `snap-width' pixels from PARENT's right edge.
- (setq snap-x pos-x)
- (setq left (- parent-right width)))
- ((and (>= right parent-right)
- (<= (- right parent-right) snap-width)
- snap-x (<= (- pos-x snap-x) snap-width))
- ;; Stay snapped when the mouse moved rightward
- ;; but not more more than `snap-width' pixels
- ;; from the time FRAME snapped.
- (setq left (- parent-right width)))
- (t
- ;; Unsnap when the mouse moved rightward more
- ;; than `snap-width' pixels from the time FRAME
- ;; snapped.
- (setq snap-x nil)))))
-
+ ((and (> left parent-left)
+ (<= (- left parent-left) snap-width))
+ ;; Snap when the mouse moved leftward and FRAME's
+ ;; left edge would end up within `snap-width'
+ ;; pixels from PARENT's left edge.
+ (setq snap-x last-x)
+ (setq left parent-left))
+ ((and (<= left parent-left)
+ (<= (- parent-left left) snap-width)
+ snap-x (<= (- snap-x last-x) snap-width))
+ ;; Stay snapped when the mouse moved leftward but
+ ;; not more than `snap-width' pixels from the time
+ ;; FRAME snapped.
+ (setq left parent-left))
+ (t
+ ;; Unsnap when the mouse moved more than
+ ;; `snap-width' pixels leftward from the time
+ ;; FRAME snapped.
+ (setq snap-x nil))))
+ ((> last-x first-x)
+ (setq right (+ left native-width))
(cond
- ((< pos-y last-y)
- (cond
- ((and (> top parent-top)
- (<= (- top parent-top) snap-width))
- ;; Snap when the mouse moved upward and FRAME's
- ;; top edge would end up within `snap-width'
- ;; pixels from PARENT's top edge.
- (setq snap-y pos-y)
- (setq top parent-top))
- ((and (<= top parent-top)
- (<= (- parent-top top) snap-width)
- snap-y (<= (- snap-y pos-y) snap-width))
- ;; Stay snapped when the mouse moved upward but
- ;; not more more than `snap-width' pixels from
- ;; the time FRAME snapped.
- (setq top parent-top))
- (t
- ;; Unsnap when the mouse moved upward more than
- ;; `snap-width' pixels from the time FRAME
- ;; snapped.
- (setq snap-y nil))))
- ((> pos-y last-y)
- (setq bottom (+ top height))
- (cond
- ((and (< bottom parent-bottom)
- (<= (- parent-bottom bottom) snap-width))
- ;; Snap when the mouse moved downward and
- ;; FRAME's bottom edge would end up within
- ;; `snap-width' pixels from PARENT's bottom
- ;; edge.
- (setq snap-y pos-y)
- (setq top (- parent-bottom height)))
- ((and (>= bottom parent-bottom)
- (<= (- bottom parent-bottom) snap-width)
- snap-y (<= (- pos-y snap-y) snap-width))
- ;; Stay snapped when the mouse moved downward
- ;; but not more more than `snap-width' pixels
- ;; from the time FRAME snapped.
- (setq top (- parent-bottom height)))
- (t
- ;; Unsnap when the mouse moved downward more
- ;; than `snap-width' pixels from the time FRAME
- ;; snapped.
- (setq snap-y nil))))))
-
- ;; If requested, constrain FRAME's draggable areas to
- ;; PARENT's edges. The `top-visible' parameter should
- ;; be set when FRAME has a draggable header-line. If
- ;; set to a number, it ascertains that the top of
- ;; FRAME is always constrained to the top of PARENT
- ;; and that at least as many pixels of FRAME as
- ;; specified by that number are visible on each of the
- ;; three remaining sides of PARENT.
- ;;
- ;; The `bottom-visible' parameter should be set when
- ;; FRAME has a draggable mode-line. If set to a
- ;; number, it ascertains that the bottom of FRAME is
- ;; always constrained to the bottom of PARENT and that
- ;; at least as many pixels of FRAME as specified by
- ;; that number are visible on each of the three
- ;; remaining sides of PARENT.
- (let ((par (frame-parameter frame 'top-visible))
- bottom-visible)
- (unless par
- (setq par (frame-parameter frame 'bottom-visible))
- (setq bottom-visible t))
- (when (and (numberp par) parent-edges)
- (setq left
- (max (min (- parent-right par) left)
- (+ (- parent-left width) par)))
- (setq top
- (if bottom-visible
- (min (max top (- parent-top (- height par)))
- (- parent-bottom height))
- (min (max top parent-top)
- (- parent-bottom par))))))
-
- ;; Use `modify-frame-parameters' since `left' and
- ;; `top' may want to move FRAME out of its PARENT.
- (modify-frame-parameters
- frame
- `((left . (+ ,left)) (top . (+ ,top)))))))
- (setq last-x pos-x)
- (setq last-y pos-y))))
- (old-track-mouse track-mouse))
+ ((and (< right parent-right)
+ (<= (- parent-right right) snap-width))
+ ;; Snap when the mouse moved rightward and FRAME's
+ ;; right edge would end up within `snap-width'
+ ;; pixels from PARENT's right edge.
+ (setq snap-x last-x)
+ (setq left (- parent-right native-width)))
+ ((and (>= right parent-right)
+ (<= (- right parent-right) snap-width)
+ snap-x (<= (- last-x snap-x) snap-width))
+ ;; Stay snapped when the mouse moved rightward but
+ ;; not more more than `snap-width' pixels from the
+ ;; time FRAME snapped.
+ (setq left (- parent-right native-width)))
+ (t
+ ;; Unsnap when the mouse moved rightward more than
+ ;; `snap-width' pixels from the time FRAME
+ ;; snapped.
+ (setq snap-x nil)))))
+ (cond
+ ((< last-y first-y)
+ (cond
+ ((and (> top parent-top)
+ (<= (- top parent-top) snap-width))
+ ;; Snap when the mouse moved upward and FRAME's
+ ;; top edge would end up within `snap-width'
+ ;; pixels from PARENT's top edge.
+ (setq snap-y last-y)
+ (setq top parent-top))
+ ((and (<= top parent-top)
+ (<= (- parent-top top) snap-width)
+ snap-y (<= (- snap-y last-y) snap-width))
+ ;; Stay snapped when the mouse moved upward but
+ ;; not more more than `snap-width' pixels from the
+ ;; time FRAME snapped.
+ (setq top parent-top))
+ (t
+ ;; Unsnap when the mouse moved upward more than
+ ;; `snap-width' pixels from the time FRAME
+ ;; snapped.
+ (setq snap-y nil))))
+ ((> last-y first-y)
+ (setq bottom (+ top native-height))
+ (cond
+ ((and (< bottom parent-bottom)
+ (<= (- parent-bottom bottom) snap-width))
+ ;; Snap when the mouse moved downward and FRAME's
+ ;; bottom edge would end up within `snap-width'
+ ;; pixels from PARENT's bottom edge.
+ (setq snap-y last-y)
+ (setq top (- parent-bottom native-height)))
+ ((and (>= bottom parent-bottom)
+ (<= (- bottom parent-bottom) snap-width)
+ snap-y (<= (- last-y snap-y) snap-width))
+ ;; Stay snapped when the mouse moved downward but
+ ;; not more more than `snap-width' pixels from the
+ ;; time FRAME snapped.
+ (setq top (- parent-bottom native-height)))
+ (t
+ ;; Unsnap when the mouse moved downward more than
+ ;; `snap-width' pixels from the time FRAME
+ ;; snapped.
+ (setq snap-y nil))))))
+
+ ;; If requested, constrain FRAME's draggable areas to
+ ;; PARENT's edges. The `top-visible' parameter should
+ ;; be set when FRAME has a draggable header-line. If
+ ;; set to a number, it ascertains that the top of FRAME
+ ;; is always constrained to the top of PARENT and that
+ ;; at least as many pixels of FRAME as specified by that
+ ;; number are visible on each of the three remaining
+ ;; sides of PARENT.
+ ;;
+ ;; The `bottom-visible' parameter should be set when
+ ;; FRAME has a draggable mode-line. If set to a number,
+ ;; it ascertains that the bottom of FRAME is always
+ ;; constrained to the bottom of PARENT and that at least
+ ;; as many pixels of FRAME as specified by that number
+ ;; are visible on each of the three remaining sides of
+ ;; PARENT.
+ (let ((par (frame-parameter frame 'top-visible))
+ bottom-visible)
+ (unless par
+ (setq par (frame-parameter frame 'bottom-visible))
+ (setq bottom-visible t))
+ (when (and (numberp par) parent-edges)
+ (setq left
+ (max (min (- parent-right par) left)
+ (+ (- parent-left native-width) par)))
+ (setq top
+ (if bottom-visible
+ (min (max top (- parent-top (- native-height par)))
+ (- parent-bottom native-height))
+ (min (max top parent-top)
+ (- parent-bottom par))))))
+ ;; Use `modify-frame-parameters' since `left' and `top'
+ ;; may want to move FRAME out of its PARENT.
+ (modify-frame-parameters frame `((left . (+ ,left)) (top . (+ ,top))))))))
+ (old-track-mouse track-mouse))
;; Start tracking. The special value 'dragging' signals the
;; display engine to freeze the mouse pointer shape for as long
;; as we drag.
@@ -879,49 +937,49 @@ mouse-drag-left-edge
"Drag left edge of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
- (mouse-drag-frame start-event 'left))
+ (mouse-drag-frame-resize start-event 'left))
(defun mouse-drag-top-left-corner (start-event)
"Drag top left corner of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
- (mouse-drag-frame start-event 'top-left))
+ (mouse-drag-frame-resize start-event 'top-left))
(defun mouse-drag-top-edge (start-event)
"Drag top edge of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
- (mouse-drag-frame start-event 'top))
+ (mouse-drag-frame-resize start-event 'top))
(defun mouse-drag-top-right-corner (start-event)
"Drag top right corner of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
- (mouse-drag-frame start-event 'top-right))
+ (mouse-drag-frame-resize start-event 'top-right))
(defun mouse-drag-right-edge (start-event)
"Drag right edge of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
- (mouse-drag-frame start-event 'right))
+ (mouse-drag-frame-resize start-event 'right))
(defun mouse-drag-bottom-right-corner (start-event)
"Drag bottom right corner of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
- (mouse-drag-frame start-event 'bottom-right))
+ (mouse-drag-frame-resize start-event 'bottom-right))
(defun mouse-drag-bottom-edge (start-event)
"Drag bottom edge of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
- (mouse-drag-frame start-event 'bottom))
+ (mouse-drag-frame-resize start-event 'bottom))
(defun mouse-drag-bottom-left-corner (start-event)
"Drag bottom left corner of a frame with the mouse.
START-EVENT is the starting mouse event of the drag action."
(interactive "e")
- (mouse-drag-frame start-event 'bottom-left))
+ (mouse-drag-frame-resize start-event 'bottom-left))
(defcustom mouse-select-region-move-to-beginning nil
"Effect of selecting a region extending backward from double click.
diff --git a/src/frame.c b/src/frame.c
index 88d6f22fc0..9ec5c24b22 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -5941,6 +5941,7 @@ syms_of_frame (void)
DEFSYM (Qxg_frame_set_char_size_1, "xg-frame-set-char-size-1");
DEFSYM (Qxg_frame_set_char_size_2, "xg-frame-set-char-size-2");
DEFSYM (Qxg_frame_set_char_size_3, "xg-frame-set-char-size-3");
+ DEFSYM (Qxg_frame_set_char_size_4, "xg-frame-set-char-size-4");
DEFSYM (Qx_set_window_size_1, "x-set-window-size-1");
DEFSYM (Qx_set_window_size_2, "x-set-window-size-2");
DEFSYM (Qx_set_window_size_3, "x-set-window-size-3");
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 6308c38f16..4cab8a5706 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -940,9 +940,8 @@ xg_frame_resized (struct frame *f, int pixelwidth, int pixelheight)
}
}
-/* Resize the outer window of frame F after changing the height.
- COLUMNS/ROWS is the size the edit area shall have after the resize. */
-
+/** Resize the outer window of frame F. WIDTH and HEIGHT are the new
+ pixel sizes of F's text area. */
void
xg_frame_set_char_size (struct frame *f, int width, int height)
{
@@ -953,6 +952,7 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
int totalheight
= pixelheight + FRAME_TOOLBAR_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f);
int totalwidth = pixelwidth + FRAME_TOOLBAR_WIDTH (f);
+ bool was_visible = false;
if (FRAME_PIXEL_HEIGHT (f) == 0)
return;
@@ -995,12 +995,35 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
totalwidth, gheight);
}
+ else if (FRAME_PARENT_FRAME (f) && FRAME_VISIBLE_P (f)
+ && EQ (x_gtk_resize_child_frames, Qhide))
+ {
+ was_visible = true;
+
+ if (totalwidth != gwidth || totalheight != gheight)
+ {
+ frame_size_history_add
+ (f, Qxg_frame_set_char_size_4, width, height,
+ list2i (totalwidth, totalheight));
+ block_input ();
+ gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
+ unblock_input ();
+
+ gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+ totalwidth, totalheight);
+
+ block_input ();
+ gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
+ unblock_input ();
+
+ fullscreen = Qnil;
+ }
+ }
else
{
frame_size_history_add
(f, Qxg_frame_set_char_size_3, width, height,
list2i (totalwidth, totalheight));
-
gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
totalwidth, totalheight);
fullscreen = Qnil;
@@ -1016,7 +1039,7 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
size as fast as possible.
For unmapped windows, we can set rows/cols. When
the frame is mapped again we will (hopefully) get the correct size. */
- if (FRAME_VISIBLE_P (f))
+ if (FRAME_VISIBLE_P (f) && !was_visible)
{
/* Must call this to flush out events */
(void)gtk_events_pending ();
diff --git a/src/xfns.c b/src/xfns.c
index 276ea1c393..f32056ff03 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -861,6 +861,12 @@ x_set_parent_frame (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
(FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
p ? FRAME_X_WINDOW (p) : DefaultRootWindow (FRAME_X_DISPLAY (f)),
f->left_pos, f->top_pos);
+#ifdef USE_GTK
+ if (EQ (x_gtk_resize_child_frames, Qresize_mode))
+ gtk_container_set_resize_mode
+ (GTK_CONTAINER (FRAME_GTK_OUTER_WIDGET (f)),
+ p ? GTK_RESIZE_IMMEDIATE : GTK_RESIZE_QUEUE);
+#endif
unblock_input ();
fset_parent_frame (f, new_value);
@@ -4084,6 +4090,11 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
block_input ();
XReparentWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
FRAME_X_WINDOW (p), f->left_pos, f->top_pos);
+#ifdef USE_GTK
+ if (EQ (x_gtk_resize_child_frames, Qresize_mode))
+ gtk_container_set_resize_mode
+ (GTK_CONTAINER (FRAME_GTK_OUTER_WIDGET (f)), GTK_RESIZE_IMMEDIATE);
+#endif
unblock_input ();
}
@@ -7742,6 +7753,22 @@ frames (each of which corresponds to one page). Each frame should be
#endif /* USE_GTK */
#endif /* USE_CAIRO */
+#ifdef USE_GTK
+#ifdef HAVE_GTK3
+DEFUN ("x-gtk-debug", Fx_gtk_debug, Sx_gtk_debug, 1, 1, 0,
+ doc: /* Toggle interactive GTK debugging. */)
+ (Lisp_Object enable)
+{
+ gboolean enable_debug = !NILP (enable);
+
+ block_input ();
+ gtk_window_set_interactive_debugging (enable_debug);
+ unblock_input ();
+
+ return NILP (enable) ? Qnil : Qt;
+}
+#endif /* HAVE_GTK3 */
+#endif /* USE_GTK */
\f
/***********************************************************************
Initialization
@@ -7810,6 +7837,8 @@ syms_of_xfns (void)
DEFSYM (Qfont_parameter, "font-parameter");
DEFSYM (Qmono, "mono");
DEFSYM (Qassq_delete_all, "assq-delete-all");
+ DEFSYM (Qhide, "hide");
+ DEFSYM (Qresize_mode, "resize-mode");
#ifdef USE_CAIRO
DEFSYM (Qpdf, "pdf");
@@ -7986,6 +8015,28 @@ syms_of_xfns (void)
When using Gtk+ tooltips, the tooltip face is not used. */);
x_gtk_use_system_tooltips = true;
+ DEFVAR_LISP ("x-gtk-resize-child-frames", x_gtk_resize_child_frames,
+ doc: /* If non-nil, resize child frames specially with GTK builds.
+If this is nil, resize child frames like any other frames. This is the
+default and usually works with most desktops. Some desktop environments
+(GNOME shell in particular when using the mutter window manager),
+however, may refuse to resize a child frame when Emacs is built with
+GTK3. For those environments, the two settings below are provided.
+
+If this equals the symbol 'hide', Emacs temporarily hides the child
+frame during resizing. This approach seems to work reliably, may
+however induce some flicker when the frame is made visible again.
+
+If this equals the symbol 'resize-mode', Emacs uses GTK's resize mode to
+always trigger an immediate resize of the child frame. This method is
+deprecated by GTK and may not work in future versions of that toolkit.
+It also may freeze Emacs when used with other desktop environments. It
+avoids, however, the unpleasent flicker induced by the hiding approach.
+
+This variable is considered a temporary workaround and will be hopefully
+eliminated in future versions of Emacs. */);
+ x_gtk_resize_child_frames = Qnil;
+
/* Tell Emacs about this window system. */
Fprovide (Qx, Qnil);
@@ -8101,4 +8152,9 @@ syms_of_xfns (void)
defsubr (&Sx_print_frames_dialog);
#endif
#endif
+#ifdef USE_GTK
+#ifdef HAVE_GTK3
+ defsubr (&Sx_gtk_debug);
+#endif
+#endif
}
diff --git a/src/xterm.c b/src/xterm.c
index 21d99f0c7b..971f374764 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -10612,26 +10612,29 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, int change_
modified_left, modified_top);
#endif
- x_sync_with_move (f, f->left_pos, f->top_pos,
- FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN);
-
- /* change_gravity is non-zero when this function is called from Lisp to
- programmatically move a frame. In that case, we call
- x_check_expected_move to discover if we have a "Type A" or "Type B"
- window manager, and, for a "Type A" window manager, adjust the position
- of the frame.
-
- We call x_check_expected_move if a programmatic move occurred, and
- either the window manager type (A/B) is unknown or it is Type A but we
- need to compute the top/left offset adjustment for this frame. */
-
- if (change_gravity != 0
- && !FRAME_PARENT_FRAME (f)
- && (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
- || (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A
- && (FRAME_X_OUTPUT (f)->move_offset_left == 0
- && FRAME_X_OUTPUT (f)->move_offset_top == 0))))
- x_check_expected_move (f, modified_left, modified_top);
+ /* 'x_sync_with_move' is too costly for dragging child frames. */
+ if (!FRAME_PARENT_FRAME (f))
+ {
+ x_sync_with_move (f, f->left_pos, f->top_pos,
+ FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN);
+
+ /* change_gravity is non-zero when this function is called from Lisp to
+ programmatically move a frame. In that case, we call
+ x_check_expected_move to discover if we have a "Type A" or "Type B"
+ window manager, and, for a "Type A" window manager, adjust the position
+ of the frame.
+
+ We call x_check_expected_move if a programmatic move occurred, and
+ either the window manager type (A/B) is unknown or it is Type A but we
+ need to compute the top/left offset adjustment for this frame. */
+
+ if (change_gravity != 0
+ && (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
+ || (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A
+ && (FRAME_X_OUTPUT (f)->move_offset_left == 0
+ && FRAME_X_OUTPUT (f)->move_offset_top == 0))))
+ x_check_expected_move (f, modified_left, modified_top);
+ }
unblock_input ();
}
next prev parent reply other threads:[~2020-03-13 17:46 UTC|newest]
Thread overview: 197+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-10 2:34 Emacs's set-frame-size can not work well with gnome-shell? tumashu
2020-01-10 9:56 ` martin rudalics
2020-01-11 1:29 ` tumashu
2020-01-11 7:50 ` martin rudalics
2020-01-11 9:56 ` Dmitry Gutov
2020-01-11 10:19 ` martin rudalics
2020-01-11 10:21 ` Dmitry Gutov
2020-01-11 10:35 ` martin rudalics
2020-01-11 11:21 ` Dmitry Gutov
2020-01-11 13:45 ` martin rudalics
2020-01-14 2:09 ` Dmitry Gutov
2020-01-14 15:50 ` martin rudalics
2020-01-15 1:31 ` Dmitry Gutov
2020-01-15 8:08 ` martin rudalics
2020-01-15 23:53 ` Dmitry Gutov
2020-01-16 8:03 ` martin rudalics
2020-01-16 8:15 ` Dmitry Gutov
2020-01-16 9:18 ` martin rudalics
2020-01-16 9:27 ` Dmitry Gutov
2020-01-16 9:44 ` martin rudalics
2020-01-16 10:12 ` Dmitry Gutov
2020-01-16 10:22 ` martin rudalics
2020-01-16 15:03 ` Dmitry Gutov
2020-01-16 18:33 ` martin rudalics
[not found] ` <15405719-d58d-44db-f1df-ad3bb272b2fc@yandex.ru>
[not found] ` <aba0683f-466c-76cf-9024-e18bfc9fdc94@gmx.at>
2020-01-18 2:05 ` Dmitry Gutov
2020-01-18 2:29 ` Dmitry Gutov
2020-01-18 8:34 ` martin rudalics
2020-01-18 12:27 ` Dmitry Gutov
2020-01-18 13:48 ` martin rudalics
2020-01-19 2:45 ` Dmitry Gutov
2020-01-19 8:52 ` martin rudalics
2020-01-20 14:14 ` Dmitry Gutov
2020-01-20 15:57 ` martin rudalics
2020-01-20 22:20 ` Dmitry Gutov
2020-01-21 8:29 ` martin rudalics
2020-01-21 11:36 ` Dmitry Gutov
2020-01-21 16:11 ` martin rudalics
2020-01-21 21:33 ` Dmitry Gutov
2020-01-22 9:07 ` martin rudalics
2020-01-22 10:57 ` Dmitry Gutov
2020-01-18 8:32 ` martin rudalics
2020-01-20 13:37 ` Dmitry Gutov
2020-01-20 15:57 ` martin rudalics
2020-01-20 23:02 ` Dmitry Gutov
2020-01-21 8:29 ` martin rudalics
2020-01-21 12:11 ` Dmitry Gutov
2020-01-21 16:12 ` martin rudalics
2020-01-21 22:26 ` Dmitry Gutov
2020-01-22 9:08 ` martin rudalics
2020-01-22 11:35 ` Dmitry Gutov
2020-01-22 13:18 ` tumashu
2020-01-22 13:32 ` Dmitry Gutov
2020-01-22 16:19 ` Eli Zaretskii
2020-01-22 17:36 ` martin rudalics
2020-01-22 21:15 ` Dmitry Gutov
2020-01-25 8:41 ` martin rudalics
2020-01-25 10:09 ` Dmitry Gutov
2020-01-25 12:10 ` martin rudalics
2020-01-26 11:59 ` Dmitry Gutov
2020-01-26 17:38 ` martin rudalics
2020-01-26 20:50 ` Dmitry Gutov
2020-01-28 9:46 ` martin rudalics
2020-01-28 15:19 ` Dmitry Gutov
2020-01-28 16:20 ` martin rudalics
2020-01-30 2:14 ` Dmitry Gutov
2020-01-27 19:17 ` martin rudalics
2020-01-27 21:15 ` Dmitry Gutov
2020-01-28 9:47 ` martin rudalics
2020-01-30 2:10 ` Dmitry Gutov
2020-01-30 9:38 ` martin rudalics
2020-01-30 17:21 ` martin rudalics
2020-01-30 18:15 ` Dmitry Gutov
2020-01-30 18:41 ` martin rudalics
2020-01-31 1:22 ` Dmitry Gutov
2020-01-31 9:29 ` martin rudalics
2020-01-31 11:52 ` Dmitry Gutov
2020-01-31 15:44 ` martin rudalics
2020-01-31 22:22 ` Dmitry Gutov
2020-02-01 9:35 ` martin rudalics
2020-02-05 1:39 ` Dmitry Gutov
2020-02-05 9:15 ` martin rudalics
2020-02-10 7:06 ` Dmitry Gutov
2020-02-10 17:53 ` martin rudalics
2020-02-10 22:40 ` Dmitry Gutov
2020-02-10 7:22 ` Dmitry Gutov
2020-02-10 17:54 ` martin rudalics
2020-02-10 22:49 ` Dmitry Gutov
2020-02-13 18:42 ` martin rudalics
2020-02-13 23:48 ` Dmitry Gutov
2020-02-14 8:48 ` martin rudalics
2020-02-15 22:31 ` Dmitry Gutov
2020-02-16 10:01 ` martin rudalics
2020-02-16 20:47 ` Dmitry Gutov
2020-02-17 18:20 ` martin rudalics
2020-02-21 11:03 ` Dmitry Gutov
2020-02-21 11:13 ` Dmitry Gutov
2020-02-21 16:08 ` martin rudalics
2020-02-24 0:11 ` Dmitry Gutov
2020-02-26 17:30 ` martin rudalics
2020-02-28 16:32 ` martin rudalics
2020-03-03 13:50 ` Dmitry Gutov
2020-03-03 14:40 ` martin rudalics
2020-03-03 18:27 ` Dmitry Gutov
2020-03-04 17:29 ` martin rudalics
2020-03-06 23:38 ` Dmitry Gutov
2020-03-07 0:07 ` Dmitry Gutov
2020-03-06 23:03 ` Dmitry Gutov
2020-02-16 23:01 ` Dmitry Gutov
2020-02-17 18:21 ` martin rudalics
2020-02-21 14:18 ` Dmitry Gutov
2020-02-21 16:08 ` martin rudalics
2020-02-23 9:22 ` Dmitry Gutov
2020-02-26 17:30 ` martin rudalics
2020-03-06 23:32 ` Dmitry Gutov
2020-03-09 9:03 ` martin rudalics
2020-03-12 0:22 ` Dmitry Gutov
2020-03-12 8:23 ` martin rudalics
2020-03-13 16:57 ` Dmitry Gutov
2020-03-13 17:46 ` martin rudalics [this message]
2020-03-16 19:51 ` Dmitry Gutov
2020-03-17 9:38 ` martin rudalics
2020-03-17 11:22 ` Dmitry Gutov
2020-03-31 17:04 ` martin rudalics
2020-04-03 11:09 ` Eli Zaretskii
2020-04-03 15:08 ` martin rudalics
2020-04-03 16:08 ` martin rudalics
2020-04-03 19:07 ` Dmitry Gutov
2020-04-04 8:51 ` Eli Zaretskii
2020-04-04 9:02 ` martin rudalics
2020-04-04 9:30 ` Eli Zaretskii
2020-04-06 9:03 ` martin rudalics
2020-04-06 13:26 ` Eli Zaretskii
2020-04-07 8:32 ` martin rudalics
2020-04-07 14:04 ` Eli Zaretskii
2020-04-06 18:36 ` Dmitry Gutov
2020-04-07 8:33 ` martin rudalics
2020-04-07 13:19 ` Dmitry Gutov
2020-04-12 6:44 ` Andreas Schwab
2020-04-12 7:23 ` Eli Zaretskii
2020-04-12 7:37 ` Andreas Schwab
2020-04-12 8:03 ` martin rudalics
2020-04-06 22:51 ` Dmitry Gutov
2020-04-07 8:33 ` martin rudalics
2020-04-07 14:25 ` Dmitry Gutov
2020-04-07 14:39 ` Robert Pluim
2020-04-07 14:50 ` Dmitry Gutov
2020-04-07 15:37 ` Robert Pluim
2020-04-07 19:25 ` Dmitry Gutov
2020-04-08 7:59 ` Robert Pluim
2020-04-08 10:37 ` Dmitry Gutov
2020-04-08 12:12 ` Robert Pluim
2020-04-08 8:31 ` Support
2020-04-08 8:45 ` martin rudalics
2020-04-08 9:03 ` Adrián Medraño Calvo
2020-04-08 9:25 ` martin rudalics
2020-02-14 9:52 ` martin rudalics
2020-02-15 22:49 ` Dmitry Gutov
2020-02-16 10:01 ` martin rudalics
2020-01-27 23:20 ` Dmitry Gutov
2020-01-27 23:32 ` Dmitry Gutov
2020-01-28 9:48 ` martin rudalics
2020-01-28 15:39 ` Dmitry Gutov
2020-01-28 16:20 ` martin rudalics
2020-01-28 9:48 ` martin rudalics
2020-01-28 15:51 ` Dmitry Gutov
2020-01-22 17:35 ` martin rudalics
2020-01-22 22:40 ` tumashu
2020-01-25 8:41 ` martin rudalics
2020-01-25 10:17 ` Dmitry Gutov
2020-01-25 10:29 ` Eli Zaretskii
2020-01-25 10:52 ` Dmitry Gutov
2020-01-25 12:11 ` martin rudalics
2020-01-25 23:01 ` Dmitry Gutov
2020-01-26 8:43 ` martin rudalics
2020-01-26 11:02 ` Dmitry Gutov
2020-01-26 15:32 ` martin rudalics
2020-01-26 21:35 ` Dmitry Gutov
2020-01-28 9:46 ` martin rudalics
2020-01-30 2:23 ` Dmitry Gutov
2020-01-30 9:38 ` martin rudalics
2020-01-30 17:32 ` Dmitry Gutov
2020-01-30 18:04 ` martin rudalics
2020-01-30 17:42 ` Dmitry Gutov
2020-01-30 18:04 ` martin rudalics
2020-01-26 11:03 ` Dmitry Gutov
2020-01-23 0:21 ` Dmitry Gutov
2020-01-23 0:39 ` tumashu
2020-01-25 8:42 ` martin rudalics
2020-01-16 0:04 ` Dmitry Gutov
2020-01-16 8:04 ` martin rudalics
2020-01-16 8:25 ` Dmitry Gutov
2020-01-11 10:36 ` tumashu
2020-01-11 13:45 ` martin rudalics
-- strict thread matches above, loose matches on Subject: below --
2020-01-22 8:04 tumashu
2020-01-22 9:09 ` martin rudalics
2020-01-22 10:03 ` tumashu
2020-01-22 17:33 ` martin rudalics
2020-01-22 15:55 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5b27dc36-df18-d188-eab3-8bf546a8c24a@gmx.at \
--to=rudalics@gmx.at \
--cc=dgutov@yandex.ru \
--cc=emacs-devel@gnu.org \
--cc=tumashu@163.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.