From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: joakim@verona.se Newsgroups: gmane.emacs.devel Subject: Re: Rethinking the design of xwidgets Date: Tue, 13 Oct 2020 00:18:46 +0200 Message-ID: <877drvw0jd.fsf@tanaka.verona.se> References: <864kmzupp0.fsf@akirakyle.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="32853"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) Cc: emacs-devel@gnu.org To: Akira Kyle Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Tue Oct 13 00:19:51 2020 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kS6AZ-0008Oj-1X for ged-emacs-devel@m.gmane-mx.org; Tue, 13 Oct 2020 00:19:51 +0200 Original-Received: from localhost ([::1]:53430 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kS6AY-0003I6-4f for ged-emacs-devel@m.gmane-mx.org; Mon, 12 Oct 2020 18:19:50 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:33414) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kS69p-0002oT-A6 for emacs-devel@gnu.org; Mon, 12 Oct 2020 18:19:05 -0400 Original-Received: from smtp.outgoing.loopia.se ([93.188.3.37]:64461) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kS69l-0006uD-HC for emacs-devel@gnu.org; Mon, 12 Oct 2020 18:19:03 -0400 Original-Received: from s807.loopia.se (localhost [127.0.0.1]) by s807.loopia.se (Postfix) with ESMTP id 7F78B2E80BD3 for ; Tue, 13 Oct 2020 00:18:49 +0200 (CEST) Original-Received: from s630.loopia.se (unknown [172.22.191.5]) by s807.loopia.se (Postfix) with ESMTP id 60CB32E38820; Tue, 13 Oct 2020 00:18:49 +0200 (CEST) Original-Received: from s474.loopia.se (unknown [172.22.191.5]) by s630.loopia.se (Postfix) with ESMTP id 53D9B13B929C; Tue, 13 Oct 2020 00:18:49 +0200 (CEST) X-Virus-Scanned: amavisd-new at amavis.loopia.se Original-Received: from s499.loopia.se ([172.22.191.5]) by s474.loopia.se (s474.loopia.se [172.22.190.14]) (amavisd-new, port 10024) with LMTP id mYL5MANknEn8; Tue, 13 Oct 2020 00:18:47 +0200 (CEST) X-Loopia-Auth: user X-Loopia-User: joakim.verona@chimeslab.se X-Loopia-Originating-IP: 193.234.148.196 Original-Received: from tanaka.verona.se (unknown [193.234.148.196]) (Authenticated sender: joakim.verona@chimeslab.se) by s499.loopia.se (Postfix) with ESMTPSA id 921831CDE38D; Tue, 13 Oct 2020 00:18:47 +0200 (CEST) In-Reply-To: <864kmzupp0.fsf@akirakyle.com> (Akira Kyle's message of "Mon, 12 Oct 2020 14:58:19 -0600") Received-SPF: pass client-ip=93.188.3.37; envelope-from=joakim@verona.se; helo=smtp.outgoing.loopia.se X-detected-operating-system: by eggs.gnu.org: First seen = 2020/10/12 18:18:57 X-ACL-Warn: Detected OS = FreeBSD 9.x or newer [fuzzy] X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:257502 Archived-At: Akira Kyle writes: > Hi all, > > If you don't care about the motivation and background for this problem > skip the next two paragraphs. > > One of my primary uses of emacs is as a scientific notebook utilizing > org mode's support for literate programming to interweave prose, > LaTeX, and code. I find this to be far more powerful and comfortable > than using the Jupyter notebooks which have quickly become incredibly > popular for such scientific computing. However the biggest pain point > I have is due to Emacs' relatively poor capabilities for interfacing > with objects other than text. Sure Emacs can display images ok, but > I'm not aware of any way to get emacs to display more dynamic > content. Furthermore I always want to be able to do more inside Emacs, > and the one other application I spend as much time in as I spend in > Emacs is a browser. Unfortunately I can't even really use eww for the > simplest of my web browsing tasks such as looking up documentation as > it usually fails to adequately render the variety of ways websites > embed mathematics. > > This has all led me to be interested in ways to enhance Emacs' display > capabilities. The two projects I've come across that do this are the > experimental xwidgets configuration and the Emacs Application > Framework (EAF) [1]. Unfortunately EAF uses Qt to reparent a window > into emacs and Python to do two way RPC with elisp. IMO it isn't a > very emacsy way to enhance Emacs' display capabilites and is limited > to just taking over a whole window rather than being embedded as part > of a buffer (key to supporting dynamic content such as an interactive > inline plot inside an org mode document). That leaves xwidgets which > seems to be somewhat incomplete, unused, and neglected. I've been > poking around the xwidgets code and I really like the concept, however > the implementation seems to need some more thought and work. > > I see two fundamental issues with the current xwidget code. The first > is that in order to add a new type of widget, one must integrate it > into the C portion of Emacs' codebase and expose relevant > functionality to elisp. The difficulty of navigating how xwidgets are > integrated into redisplay and how to expose the inherently event > driven nature of GUI toolkits into elisp in a safe way is a big hurdle > to hacking on xwidgets. In the last decade of this features existence > no one has added any additional xwidgets besides the original webkit > one (see make-xwidget). This despite the fact that xwidgets were > originally designed to allow embedding of any gtk widgets such as > buttons, sliders, image views, opengl contexts [2]. Recently support > for webkit using the native cocoa framework was added for the ns > toolkit demonstrating that this feature need not be tied to a specific > GUI toolkit. The second issue is that most interesting applications > of xwidgets will likely need to use some external C > library. Historically, package maintainers have been hesitant to > package emacs with xwidgets support due to the additional dependency > on webkitgtk, which was often not kept current with security patches > [3]. In the long run I don't think adding extra dependencies to emacs > just for the sake of some specific xwidget is worth it. > > That leads me to my following proposal to rethink the design of > xwidgets. Given that Emacs now has support for dynamic modules and it > is now enabled by default, I propose exposing an interface for dynamic > modules to define custom xwidgets. I believe this would be a good way > to solve the two fundamental issues with the current xwidgets > implementation that I described above. Having a well defined interface > means one wouldn't have to deal with debugging subtle redisplay and > lisp interpreter issues when creating a custom xwidget > type. Furthermore any external library needed for a custom xwidget > type will only be required if one chooses to use that xwidget type and > would keep such dependencies out of Emacs itself. > > I've already done a proof of concept prototype to convince myself that > this is possible. I first modified the xwidget display spec to include > a field which is expected to contain a function to initialize an > xwidget view. When redisplay acts on this spec, the xwidgets code > calls this function with the xwidget display spec and expects a > user_ptr Lisp_Object to be returned which wraps a pointer to a > GtkWidget. The xwidgets code then adds this widget to an appropriate > container that it uses to ensure the widget is moved when the position > or clipping of its glyph changes. I then define this xwidget view > initialization function in a dynamic module. > > Since every window containing the xwidget has its own view, and hence > separate GtkWidget instance, it is then up to the dynamic module to > define the how to handle the updating of each view based on some > common model each is supposed to represent. This works around the > limitation that in most GUI toolkits each widget can only have one > view. Thus for something like the webkitgtk widget, one implementation > might choose to do offscreen rendering (as is currently done) so that > all windows displaying the widget are updated together when, say, one > of them is scrolled. While another implementation might decide each > view gets a separate view of the same webpage and scrolling one will > not scroll the other (which is what the cocoa webkit implementation > should probably do, but it is currently only limited to being > displayed in a single window). > > I'd be interested in any thoughts anyone might have about this > proposal and if some changes along this line might have some chance of > being accepted in master someday. I've always wanted to dig into the > nity grity c code of emacs and this has finally given me the excuse to > do so! Akira As the original author of the xwidgets code, I'm happy that you are taking an interest in moving the idea forward, and I like your ideas. I had these ideas in the same vein originally: - Use the gnome object system to create and manipulate xwidgets dynamically. There was a prototype for this in the original xwidget branch. It worked, but it was tedious figuring out how to map between elisp types and gtk types. - In those cases when the gobject bridge didnt behave, use the emacs module system for shims(the approach you describe above) Some questions: - The original xwidgets were designed to allow several views to the same xwidget using gtk reflection, as you describe. When I tried using separate gtk controllers on screen, they didnt sync very well. Did you try this and did it work well? When I worked on this I tried several different gtk components such as sliders etc. Some of the worked flaky, some worked rather well. What is you current experience trying different components? Anyway, thanks again for having a look at this! > > [1] https://github.com/manateelazycat/emacs-application-framework > [2] https://github.com/jave/xwidget-emacs > [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=843462 > -- Joakim Verona joakim@verona.se