From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.bugs Subject: bug#37667: 27.0.50; Tab Bar display problems with more than 5 tabs Date: Tue, 22 Oct 2019 01:20:42 +0300 Organization: LINKOV.NET Message-ID: <8736fl91vp.fsf@mail.linkov.net> References: <83o8yrvzgh.fsf@gnu.org> <87imownt6j.fsf@mail.linkov.net> <83eezjrbuj.fsf@gnu.org> <87sgnw2pz3.fsf@mail.linkov.net> <83o8yjke0u.fsf@gnu.org> <87lftnqbmg.fsf@mail.linkov.net> <83h84agytj.fsf@gnu.org> <87tv89opbh.fsf@mail.linkov.net> <83mue1g845.fsf@gnu.org> <83lftlg6zc.fsf@gnu.org> <87lftlk504.fsf@mail.linkov.net> <83eezceir2.fsf@gnu.org> <87pniwuwj5.fsf@mail.linkov.net> <83blufdehy.fsf@gnu.org> <878spj57dk.fsf@mail.linkov.net> <83v9sm8rs3.fsf@gnu.org> <87blubaw63.fsf@mail.linkov.net> <83zhhu34xz.fsf@gnu.org> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="48551"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) Cc: 37667@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Oct 22 00:28:19 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1iMg9z-000CTP-2j for geb-bug-gnu-emacs@m.gmane.org; Tue, 22 Oct 2019 00:28:19 +0200 Original-Received: from localhost ([::1]:48464 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iMg9x-0008OR-V3 for geb-bug-gnu-emacs@m.gmane.org; Mon, 21 Oct 2019 18:28:17 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:51156) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iMg9j-0008O4-JX for bug-gnu-emacs@gnu.org; Mon, 21 Oct 2019 18:28:05 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iMg9i-0006cO-8l for bug-gnu-emacs@gnu.org; Mon, 21 Oct 2019 18:28:03 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:49225) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iMg9i-0006cH-5X for bug-gnu-emacs@gnu.org; Mon, 21 Oct 2019 18:28:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1iMg9h-0007Ib-Ub for bug-gnu-emacs@gnu.org; Mon, 21 Oct 2019 18:28:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Juri Linkov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 21 Oct 2019 22:28:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 37667 X-GNU-PR-Package: emacs Original-Received: via spool by 37667-submit@debbugs.gnu.org id=B37667.157169687228041 (code B ref 37667); Mon, 21 Oct 2019 22:28:01 +0000 Original-Received: (at 37667) by debbugs.gnu.org; 21 Oct 2019 22:27:52 +0000 Original-Received: from localhost ([127.0.0.1]:58046 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iMg9X-0007IB-R7 for submit@debbugs.gnu.org; Mon, 21 Oct 2019 18:27:52 -0400 Original-Received: from bird.elm.relay.mailchannels.net ([23.83.212.17]:10353) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iMg9V-0007I3-NK for 37667@debbugs.gnu.org; Mon, 21 Oct 2019 18:27:50 -0400 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Original-Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 6F25D5019EA; Mon, 21 Oct 2019 22:27:48 +0000 (UTC) Original-Received: from pdx1-sub0-mail-a38.g.dreamhost.com (100-96-60-11.trex.outbound.svc.cluster.local [100.96.60.11]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id F1C475007BD; Mon, 21 Oct 2019 22:27:47 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Original-Received: from pdx1-sub0-mail-a38.g.dreamhost.com ([TEMPUNAVAIL]. [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.18.5); Mon, 21 Oct 2019 22:27:48 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Chief-Scare: 008473df355ab5c7_1571696868238_2213818668 X-MC-Loop-Signature: 1571696868238:3875786157 X-MC-Ingress-Time: 1571696868238 Original-Received: from pdx1-sub0-mail-a38.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a38.g.dreamhost.com (Postfix) with ESMTP id 3F5FE83D39; Mon, 21 Oct 2019 15:27:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; s=linkov.net; bh=HLoRHPQH4AZyKcRg6GTks7HjG14=; b= C9VhVfRckEG5U9DmhW1JdH+8VH3vOqx7FhD7wUX82o4WrP/48F7GSLUcRMd6GJ4Z jHK8BBHxQ0YZlcfbDTvNkCdoLJxwkZPU+DAsQAnmKHA7zKGDVRj21rclp6xmK466 ASHFCdtSxRgSq+5ZIGGip0LGNUX+oX8oYAK0d5yqPEY= Original-Received: from mail.jurta.org (m91-129-98-153.cust.tele2.ee [91.129.98.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a38.g.dreamhost.com (Postfix) with ESMTPSA id C043883D2A; Mon, 21 Oct 2019 15:27:42 -0700 (PDT) X-DH-BACKEND: pdx1-sub0-mail-a38 In-Reply-To: <83zhhu34xz.fsf@gnu.org> (Eli Zaretskii's message of "Mon, 21 Oct 2019 10:58:48 +0300") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:169958 Archived-At: >> But maybe tab-button granularity is fine. The only problem is that >> I still studying the code to understand where to begin. Could you suggest >> in what function to implement all this scrolling? > > I think you will need a new function. A tab-line is generated from a > Lisp string, and we don't have code for hscrolling screen lines > produced from strings (as opposed to from buffer text). > > The general idea is to identify the first (leftmost) tab you want to > be visible, and then make changes in display_mode_line to start > display from that tab. I think the first part is the more complex of > these two. format-mode-line shows an example of how to generate > display derived from Lisp and C strings without displaying anything; > you could use that for finding the X coordinate (in it.current_x) of > the beginning of the Nth tab's button. Each click on the right fringe > increases N, each click on the left decreases it. The X coordinate > you compute is the value to use for it.first_visible_x in > display_mode_line. This is so overwhelming that I'm still struggling with understanding the details of the display engine. If hscrolling was already implemented for the header-line, we could just copy the existing solution to the tab-line. So I looked how packages cope with the requirement of keeping hscrolling of the header-line in sync with hscrolling of the buffer, and found that the 'proced' package uses so simple solution that we could just do the same. This is what it does: (defun proced-header-line () "Return header line for Proced buffer." (list (propertize " " 'display (list 'space :align-to (line-number-display-width 'columns))) (if (<= (window-hscroll) (length proced-header-line)) (replace-regexp-in-string ;; preserve text properties "\\(%\\)" "\\1\\1" (substring proced-header-line (window-hscroll)))))) i.e. it just cuts scrolled content from the beginning. Adapting the same idea to the tab-line provides the workable and reliable solution with just a dozen lines of Lisp code. You can evaluate this, and everything works smoothly: (advice-add 'tab-line-format :around (lambda (orig-fun) (let ((tabs (funcall orig-fun)) (hscroll (window-parameter nil 'hscroll))) (if hscroll (nthcdr hscroll tabs) tabs))) '((name . tab-line-format-hscroll))) (defun tab-line-hscroll (&optional arg window) (let* ((hscroll (window-parameter window 'hscroll))) (set-window-parameter window 'hscroll (max 0 (min (+ (or hscroll 0) (or arg 1)) (1- (length (funcall tab-line-tabs-function)))))))) (defun tab-line-hscroll-left (&optional arg mouse-event) (interactive (list current-prefix-arg last-nonmenu-event)) (tab-line-hscroll arg (and (listp mouse-event) (posn-window (event-start mouse-event)))) (force-mode-line-update)) (defun tab-line-hscroll-right (&optional arg mouse-event) (interactive (list current-prefix-arg last-nonmenu-event)) (tab-line-hscroll (- (or arg 1)) (and (listp mouse-event) (posn-window (event-start mouse-event)))) (force-mode-line-update)) (global-set-key [tab-line mouse-4] 'tab-line-hscroll-left) (global-set-key [tab-line mouse-5] 'tab-line-hscroll-right) (global-set-key [tab-line wheel-up] 'tab-line-hscroll-left) (global-set-key [tab-line wheel-down] 'tab-line-hscroll-right) Thus mouse-wheel hscrolls the tab-line exactly like mouse-wheel hscrolls tabs in Firefox. Also these two commands can be used via M-x, and can be bound to some key that could used via a transitive keymap, e.g. some prefix initiates a key sequence, then consecutive keys continue hscrolling. Later advice-add will be moved into the body of tab-line-format.