ch11ng / exwm

Emacs X Window Manager
2.85k stars 136 forks source link

When I enlarge a floating window vertically, it actually shrinks #653

Open emacksnotes opened 5 years ago

emacksnotes commented 5 years ago

When I enlarge a floating window vertically, it actually shrinks

Screen-recording of the bug in action.

https://drive.google.com/file/d/19ZeEOlbuCxppbbX9BlOA_Nkjnx0_fuXq/view?usp=sharing

Description of the actual and expected behaviours

  1. The GNOME Terminal shrinks, when toggled from being tiled to floating. It shrinks from being a giant to dwarf.
  2. To alleviate the problem, I try 'Enlarge Window vertically'. Instead of the window growing, it actually shrinks.

(1) may or may not be a bug. But I think that terminal window shrinks too much for anyone's comfort. The command prompt--the content area--of the window is barely visible.

(2) is surely a bug.

Debug Log

Here is the debug log.

exwm-float-resize-final.txt

Notes about the Debug Log

FYI, to quickly narrow down to the relvant log lines, try matching all these timestamps

  1. the top bar of my GNOME Panel,
  2. the date in the Terminal
  3. the timestamp in the log file itself.

It is important to note that when the GNOME Terminal is really shrunk, I type date in to the shell prompt before and after the menu bar actions. Since the shell prompt is barely visible or totally hidden you may miss noticing this detail. But you can see the dates / timestamps in the final tiled terminal.

I haven't looked at the debug log yet. So, I have no comments to offer now ... Meanwhile if any of you could figure out what the problem is that will be helpful.

emacksnotes commented 5 years ago
I try 'Enlarge Window vertically'.  Instead of the window growing, it actually shrinks.

The corresponding log line is

[16:47:40] exwm-layout-enlarge-window:  (:exwm--normal-hints-min-height 102 :height 69 :delta 1 :inner-height 69 :exwm--normal-hints-max-height nil)

The above log line is created with following diff

diff --git a/exwm-layout.el b/exwm-layout.el
index 9f1e0cf74..d53f04ea3 100644
--- a/exwm-layout.el
+++ b/exwm-layout.el
@@ -472,6 +472,12 @@ windows."
            (edges (window-inside-pixel-edges))
            (inner-height (- (elt edges 3) (elt edges 1)))
            (margin (- height inner-height)))
+
+      (exwm--log "%S" (list :exwm--normal-hints-min-height exwm--normal-hints-min-height
+               :height height
+               :delta delta
+               :inner-height inner-height
+               :exwm--normal-hints-max-height exwm--normal-hints-max-height))
       (if (> delta 0)
           (if (not exwm--normal-hints-max-height)
               (cl-incf height delta)
@@ -479,6 +485,7 @@ windows."
                 (setq height nil)
               (setq height (min (+ exwm--normal-hints-max-height margin)
                                 (+ height delta)))))
+
         (if (not exwm--normal-hints-min-height)
             (cl-incf height delta)
           (if (<= inner-height exwm--normal-hints-min-height)

The lines are in exwm-layout-enlarge-window, within the t branch of cond. The lines are the first body in the let form of that branch. i.e., it goes something like

   (t
    (let* ((height (frame-pixel-height))
           (edges (window-inside-pixel-edges))
           (inner-height (- (elt edges 3) (elt edges 1)))
           (margin (- height inner-height)))

      (exwm--log "%S" (list :exwm--normal-hints-min-height exwm--normal-hints-min-height
                :height height
                :delta delta
                :inner-height inner-height
                :exwm--normal-hints-max-height exwm--normal-hints-max-height))
      (if (> delta 0)
          (if (not exwm--normal-hints-max-height)
              (cl-incf height delta)
emacksnotes commented 5 years ago

The GNOME Terminal shrinks, when toggled from being tiled to floating. It shrinks from being a giant to dwarf.

You can see this happening in the lines below. Note how the terminal geometry goes from 888x541 to 884x69. When it is expanded vertically via the menu bar, it further shrinks from 884x69 to884x45.

34 matches for "exwm--set-geometry: Setting #x4a0000a" in buffer: exwm-float-resize-final.txt
    423:[16:47:30] exwm--set-geometry:  Setting #x4a0000a to nilxnil+271+103
    436:[16:47:31] exwm--set-geometry:  Setting #x4a0000a to 888x541+273+81
    467:[16:47:31] exwm--set-geometry:  Setting #x4a0000a to 888x541+273+81
    478:[16:47:31] exwm--set-geometry:  Setting #x4a0000a to 888x541+273+81
   1984:[16:47:31] exwm--set-geometry:  Setting #x4a0000a to 884x506+273+81
   1995:[16:47:31] exwm--set-geometry:  Setting #x4a0000a to 884x506+273+81
   2025:[16:47:31] exwm--set-geometry:  Setting #x4a0000a to 884x468+273+81
   2036:[16:47:31] exwm--set-geometry:  Setting #x4a0000a to 884x468+273+81
   2066:[16:47:31] exwm--set-geometry:  Setting #x4a0000a to 884x430+273+81
   2077:[16:47:31] exwm--set-geometry:  Setting #x4a0000a to 884x430+273+81
   2107:[16:47:31] exwm--set-geometry:  Setting #x4a0000a to 884x392+273+81
   2118:[16:47:31] exwm--set-geometry:  Setting #x4a0000a to 884x392+273+81
   2148:[16:47:31] exwm--set-geometry:  Setting #x4a0000a to 884x354+273+81
   2159:[16:47:31] exwm--set-geometry:  Setting #x4a0000a to 884x354+273+81
   2189:[16:47:31] exwm--set-geometry:  Setting #x4a0000a to 884x316+273+81
   2200:[16:47:31] exwm--set-geometry:  Setting #x4a0000a to 884x316+273+81
   2266:[16:47:32] exwm--set-geometry:  Setting #x4a0000a to 884x278+273+81
   2277:[16:47:32] exwm--set-geometry:  Setting #x4a0000a to 884x278+273+81
   2307:[16:47:32] exwm--set-geometry:  Setting #x4a0000a to 884x240+273+81
   2318:[16:47:32] exwm--set-geometry:  Setting #x4a0000a to 884x240+273+81
   2348:[16:47:32] exwm--set-geometry:  Setting #x4a0000a to 884x202+273+81
   2359:[16:47:32] exwm--set-geometry:  Setting #x4a0000a to 884x202+273+81
   2389:[16:47:32] exwm--set-geometry:  Setting #x4a0000a to 884x164+273+81
   2400:[16:47:32] exwm--set-geometry:  Setting #x4a0000a to 884x164+273+81
   2430:[16:47:32] exwm--set-geometry:  Setting #x4a0000a to 884x126+273+81
   2441:[16:47:32] exwm--set-geometry:  Setting #x4a0000a to 884x126+273+81
   2471:[16:47:32] exwm--set-geometry:  Setting #x4a0000a to 884x88+273+81
   2482:[16:47:32] exwm--set-geometry:  Setting #x4a0000a to 884x88+273+81
   2512:[16:47:32] exwm--set-geometry:  Setting #x4a0000a to 884x69+273+81
   2523:[16:47:32] exwm--set-geometry:  Setting #x4a0000a to 884x69+273+81
   2862:[16:47:40] exwm--set-geometry:  Setting #x4a0000a to 884x45+273+81
   2873:[16:47:40] exwm--set-geometry:  Setting #x4a0000a to 884x45+273+81
   3266:[16:47:49] exwm--set-geometry:  Setting #x4a0000a to 1366x651+0+51
   3276:[16:47:50] exwm--set-geometry:  Setting #x4a0000a to 1366x651+0+51
ch11ng commented 5 years ago

The GNOME Terminal shrinks, when toggled from being tiled to floating. It shrinks from being a giant to dwarf.

A quirk for floating X windows in EXWM is that they can't be resized precisely, as Emacs frames can't. And if programs are not getting the size they want from WM some tend to request for another size. So if this doesn't happen every time, there's probably no calculation error involved but a result of the aforementioned quirk.

To alleviate the problem, I try 'Enlarge Window vertically'. Instead of the window growing, it actually shrinks.

This is fixed with 988f983233275b84ee3587af8a449a44d95c6752.

emacksnotes commented 5 years ago

To alleviate the problem, I try 'Enlarge Window vertically'. Instead of the window growing, it actually shrinks.

This is fixed with 988f983.

Enlarging vertically works now.

When I do Enlarge / Shrink horizontally via the menu the window size stays put, FYI. I am not sure if this behaviour is a "quirk" or a "bug". If you need a screen recording, let me know.

emacksnotes commented 5 years ago

When I do Enlarge / Shrink horizontally via the menu the window size stays put, FYI. I am not sure if this behaviour is a "quirk" or a "bug". If you need a screen recording, let me know.

For a recording of Horizontal Resizing see video / log at https://github.com/ch11ng/exwm/issues/653

ch11ng commented 5 years ago

That video seems corrupted. Have tried enlarging/shrinking other applications? It seems working here.

emacksnotes commented 4 years ago

For a recording of Horizontal Resizing see video / log at #653

That video seems corrupted. Have tried enlarging/shrinking other applications? It seems working here.

I have uploaded the video here https://gitlab.com/emacksnotes/exwm-issues/issues/1

ch11ng commented 4 years ago

According to the logs it seems enlarging/shrinking horizontally actually works. The right border should be moved while the position of the window was not changed. Perhaps a change of 1 pixel is too trivial to notice.

relevant logs: ``` [19:14:25] exwm-layout-enlarge-window: [19:14:25] exwm--set-geometry: Setting #x420002e to 824x172+nil+nil [19:14:25] exwm--set-geometry: Setting #x420002e to 824x172+nil+nil [19:14:29] exwm-layout-shrink-window: 1 [19:14:29] exwm-layout-enlarge-window: [19:14:29] exwm--set-geometry: Setting #x420002e to 824x171+nil+nil [19:14:29] exwm--set-geometry: Setting #x420002e to 824x171+nil+nil [19:14:36] exwm-layout-enlarge-window-horizontally: 1 [19:14:36] exwm-layout-enlarge-window: [19:14:36] exwm--set-geometry: Setting #x420002e to 825x171+nil+nil [19:14:36] exwm--set-geometry: Setting #x420002e to 825x171+nil+nil [19:14:42] exwm-layout-shrink-window-horizontally: 1 [19:14:42] exwm-layout-enlarge-window: [19:14:42] exwm--set-geometry: Setting #x420002e to 824x171+nil+nil [19:14:42] exwm--set-geometry: Setting #x420002e to 824x171+nil+nil ```
emacksnotes commented 4 years ago

According to the logs it seems enlarging/shrinking horizontally actually works. The right border should be moved while the position of the window was not changed. Perhaps a change of 1 pixel is too trivial to notice.

Yes, the expanding / shrinking seems to work. For visible confirmation, I tried passing C-u C-u to the command so that I could see a 16px change. Instead, I see only a 4px change.

In essence, there is a bug in how exwm handles /chained/ prefixes.

You can see the video, log etc for the above behaviour at https://gitlab.com/emacksnotes/exwm-issues/issues/1#note_252773456

ch11ng commented 4 years ago

The problem is with the command exwm-input-invoke--C-u. However it works with exwm-input-invoke--C-u\ C-u (i.e. (exwm-input-invoke-factory "C-u C-u")). It seems unread C-u twice is not exactly the same as unread two of it simultaneously. BTW C-u 16 should work.

emacksnotes commented 4 years ago

C-u C-u on a char-mode buffer doesn't send 16. Instead it sends, what is effectively a 4. https://gitlab.com/emacksnotes/exwm-issues/issues/1#note_252773456

This is what view-lossage shows when I insert 16 dashes to a bufffer

 C-u          ;; universal-argument
 C-u          ;; universal-argument-more
 C-q          ;; quoted-insert
- M-x         ;; execute-extended-command

Likewise, I would expect that the view-lossage for actions on GNOME Terminal buffer has a log for BOTH universal-argument and universal-argument-more. Instead I see two universal-argument-s as below

 <help-echo> C-S-u             ;; exwm-input--invoke--C-u
 C-u                   ;; universal-argument
 C-S-u                     ;; exwm-input--invoke--C-u
 C-u                   ;; universal-argument
 <menu-bar> <EXWM> <Enlarge window horizontally> ;; exwm-layout-enlarge-window-horizontally

The problem is with the command exwm-input-invoke--C-u. However it works with exwm-input-invoke--C-u\ C-u (i.e. (exwm-input-invoke-factory "C-u C-u")). It seems unread C-u twice is not exactly the same as unread two of it simultaneously. BTW C-u 16 should work.

This is because universal-argument uses a set-transient-map (cf. https://github.com/emacs-mirror/emacs/blob/7e387c9e5265b98dbb3b986f8ab8ac2217052831/lisp/simple.el#L4329). C-S-u /exits/ the transient map. So, the /second/ C-u instead of continuing the chain, starts a new-chain. i.e., Emacs essentially sees C-S-u C-u C-S-u C-u.

Since C-S-u is a proxy for C-u it shouldn't really exit the transient map set up by the first universal-argument. Looking at the set-transient-map (cf. https://github.com/emacs-mirror/emacs/blob/7e387c9e5265b98dbb3b986f8ab8ac2217052831/lisp/subr.el#L5144), I have a feeling that the problematic behaviour can be fixed by having the factory function re-install a transient map of it's own.

Note that the factory commands will pose a problem in /all/ cases where the command it is wrapping installs a transient map.

ch11ng commented 4 years ago

Did you mean the pre-command-hook and isearch part? Yes it seems if we install a transient map with the first C-S-u then the map installed by universal-argument won't get cleared. But I doubt when & how can we clear that map.

emacksnotes commented 4 years ago

Did you mean the pre-command-hook and isearch part? Yes it seems if we install a transient map with the first C-S-u then the map installed by universal-argument won't get cleared. But I doubt when & how can we clear that map.

I spent some time looking at the pre-command hook, exit function and clear function. I didn't have much clarity on what it is doing. There is too much passing of state via chaining. I will sleep on this problem, and examine it next weekend.

ch11ng commented 4 years ago

I'm not quite sure about that trick either. As I just tried, it didn't seem to work the way I thought.