Hi Eli, On Sat, Apr 3, 2021 at 2:56 PM Eli Zaretskii wrote: > > > Thanks, but this doesn't match my observations. > > First, I get a much smaller value for "virtual glyph" width: 5, not 9. > (Did you look at the values in "emacs -Q" or in a session where fonts > were customized?) > Indeed, the "Scale and Layout" on my monitor is set to 175% and thus the difference. Setting it back to 100% gives a a virtual-glyph width of 5px as per your correct observation with the following variable glyph width sizes: | column no. | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | | glyph | ?\s | ?* | ?s | ?c | ?r | ?a | ?t | ?c | ?h | ?* | | width (px) | 4 | 6 | 7 | 7 | 4 | 7 | 4 | 7 | 7 | 5 | | end pos (px) | 4 | 10 | 17 | 24 | 28 | 35 | 39 | 46 | 53 | 58 | > > More importantly, remember_mouse_glyph is not called at all when I > click on the tab-bar buttons, it is only called when I _move_ the > mouse. The decision whether we click on the same glyph or not is > irrelevant to tab-bar buttons, it only cares if we click on the same > _button_ as before, and that decision is made in get_tab_bar_item, > which calls x_y_to_hpos_vpos, and the latter doesn't use any > approximations of the glyph dimensions, it uses the actual pixel width > of each glyph on display. > Agreed. Though, unless I am mistaken, it appears to me that the virtual-glyph calculations performed during mouse moves over the tab-bar, do indirectly affect the calculations during a mouse click. I copied below a little sketch of how the situation appeared to me while I was debugging the issue. During a mouse move, the A.1.1 predicate is referencing the virtual-glyph, fixed glyph size, calculation from FRAME_DISPLAY_INFO's `last_mouse_glyph' done in A.1.1.2.1 and as thus it might not trigger A.1.1.1.1.1 to update MOUSE_HL_INFO when the mouse moves to a different variable-sized glyph. The MOUSE_HL_INFO value is later used during a mouse click in B.1.1.1 which, as a consequence, might miss the tab activation (i.e. B.1.1.1.1 compares the column returned from src/xdisp.c:x_y_to_hpos_vpos against a potentially stale MOUSE_HL_INFO's mouse face beg/end col range): A. src/w32term.c:w32_read_socket / (`WM_MOUSEMOVE' event) 1. src/w32term.c:w32_note_mouse_movement 1. Determine whether "Has the mouse moved off the glyph it was on at the last sighting?" by checking if the MOUSE_X and MOUSE_Y position fall outside the `RECT' of src/frame.h:FRAME_DISPLAY_INFO's `last_mouse_glyph'. If so 1. src/xdisp.c:note_mouse_highlight 1. src/xdisp.c:note_tab_bar_highlight 1. sets src/frame.h:MOUSE_HL_INFO's 1. `mouse_face_beg_col' to the glyph column under the mouse 2. `mouse_face_end_col' to the next glyph column under the mouse 2. Set src/w32term.h:FRAME_DISPLAY_INFO's `last_mouse_glyph' to the `RECT' that the glyph under the cursor occupies, by calling src/xdisp.c:remember_mouse_glyph: 1. When it is over the tab-bar, it currently uses the `virtual_glyph' method to set RECT, which assumes all glyphs on the tab-bar row have a fixed width (sourced from src/frame.h:FRAME_SMALLEST_CHAR_WIDTH). B. src/w32term.c:w32_read_socket / WM_*BUTTON* event 1. src/w32term.c:w32_handle_tab_bar_click 1. src/xdispl.c:handle_tab_bar_click 1. src/xdispl.c:get_tab_bar_item 1. Returns whether the mouse's X/Y is on the same item that was highlighted before. It does that by comparing, among other things, whether the column position HPOS returned by src/xdisp.c:x_y_to_hpos_vpos falls in the src/frame.h:MOUSE_HL_INFO's mouse face beg and end col range. 2. if the above function indicates that the mouse cursor is on the same item that was highlighted before, then it activates the tab. > > I think the actual problem is elsewhere: in handle_tab_bar_click. It > includes code that was copied from handle_tool_bar_click, and which > pays attention to the value of mouse-highlight. But tab-bar buttons > don't behave like tool-bar buttons in this regard: they don't respond > to moving the mouse pointer to them by "activating" the button. So I > think that code should be removed from handle_tab_bar_click. To wit: > turn mouse-highlight off (M-x set-variable RET mouse-highlight RET nil > RET), and clicks on tab-bar buttons miraculously start working with > 100% reliability. > This will indeed also solve the problem by removing the comparison in B.1.1 which is using the potentially stale src/frame.h:MOUSE_HL_INFO, which to me seems to be the source of the problem. And it is an even better solution, since that part of the code might have been included there only by mistake. Nice catch! Regardless of this though, assuming the above sketch is correct, shouldn't we also consider fixing the code in src/xdisp.c:remember_mouse_glyph so as to set the src/w32term.h:FRAME_DISPLAY_INFO's `last_mouse_glyph' using `text-glyph' coordinates, so as for A.1.1 to fire up based on the actual tab-bar glyph coordinates during a mouse move (so that MOUSE_HL_INFO does not contain stale information)? I can't think of a reason why we might want this to be set using virtual-glyph coords when over the tab-bar (but then, I can only see some of the pieces and not the whole picture as you do). Thanks!