To Pd dev -
I don't know if any of you remember this, but at the first Pd convention in 2004, someone (I forget who) had the idea of replacing the Pd front end by using the tcl parser but making gtk bindings in place of the tk ones. This is not the most streamlined or elegant way to replace Pd's front end, but it has the advantage of easily coexisting with the existing setup.
Well, I made a stab at doing the same thing with GTK4 - you can grab it here: http://msp.ucsd.edu/tmp/2024.09.28-pdgtk.tgz . It's about 1200 lines of code and does only a coupe of very basic things, but it allows us to guess what it would entail to do the whole job. Of the 325 calls to pdgui_v[a]mess in the PD source, it takes care of about 10 I think.
To proceed further it would be best to replace calls like <canvas-tag> itemconfigure <item-tag> -width 4 with calls to specific purpose-build tcl procedures like pdtk_canvas_configure_line_width, of which there would probably be 100 or so. I haven't done any of this since I'd like to see if the rest of you have thoughts about doing that. Proceeding that way, and perhaps taking care of 10 cases a day, I think this can be done in a month of work (and then years of followup as usual :)
I've heard it suggested that ther could be a C API in Pd that would break out all these calls, but I personally think the pdgui_vmess protocol is good enough and is much easier to manage. We could even replace the ASCII strings with a binary format without changing anything outside of s_inter_gui.c on the PD side, a binary-to-ascii converter for the tcl/tk layer, and then do away entirely with the TCL interpreter for the GTK front end, replaing it with a simple function dispatcher.
First off, I very much appreciate any effort to move away from Tcl/Tk :)
On 28.09.2024 14:01, Miller Puckette wrote:
I don't know if any of you remember this, but at the first Pd convention in 2004, someone (I forget who) had the idea of replacing the Pd front end by using the tcl parser
I think this is actually what the rest of us is trying to avoid :) The overall goal of the recent GUI refactoring efforts was explicitly to move away from Tcl-specific code towards a more general interface. pdgui_vmess() has only been the very first step. IMO https://github.com/pure-data/pure-data/pull/1765 goes into the right direction.
In general, for all built-in objects the core shouldn't have to tell the GUI how to draw it. That's the job of the GUI! I.e. we shouldn't say "draw these lines with these colors at these positions, then draw a circle with radius X and position Z", instead we should just tell "draw a 'bang' object with this size at this position". Here's a good example: https://github.com/pure-data/pure-data/pull/1765/files#diff-08294559d6a971f7...
The big question is how to handle externals that want to create their own UIs by sending Tcl commands. Generally, our UI does not know about these, so we probably need to provide raw drawing commands. Ideally, these drawing commands should not be actual Tcl commands, but more generalized. However, this would mean that all existing externals that send Tcl commands would need to be updated. We could keep a Tcl parser just for externals, at least for a transition period.
Well, I made a stab at doing the same thing with GTK4 - you can grab it here: http://msp.ucsd.edu/tmp/2024.09.28-pdgtk.tgz . It's about 1200 lines of code and does only a coupe of very basic things, but it allows us to guess what it would entail to do the whole job. Of the 325 calls to pdgui_v[a]mess in the PD source, it takes care of about 10 I think.
Why did you pick GTK specifically? What is the 2D canvas implementation like? IMO we must absolutely evaluate the quality of the canvas implementation because it's absolutely critical to performance. The Tk canvas implementation, for example, is rather bad and GUI performance on large patches with lots of GOP is horrendous. Qt, on the other hand, has a very optimized 2D canvas implementation ("QGraphicsScene") which can easily handle thousands of objects. (All items are kept in a BSP tree so it can quickly determine which area of the canvas it needs to redraw after an object has changed.)
I see that you're using Cairo. Have you tested with lots of primitives? Reports like https://stackoverflow.com/questions/63114699/extremely-bad-cairo-performance... don't sound encouraging...
The most important questions is: what happens if you change something in the canvas? Does it need to redraw the whole thing? Or can it figure out which parts it needs to redraw?
---
Finally, I see that the GUI would still be in separate process. Why is that? All other audio applications I know simply run the UI on the main thread. Instead of sending the GUI messages over a TCP socket, we can just put them on a (lockfree) FIFO which is polled by the UI thread.
(I'm curious: what was the reason for running the GUI as a separate process in the first place?)
The only reason I can think of for running the UI in a separate process would be remote GUIs. However, out-of-process GUIs can be implemented on top of in-process GUIs, using the the same binary on both sides:
1. the core keeps throwing messages on the FIFO, but instead of an UI thread, we have a network thread that forwards the messages to a TCP socket.
2. the GUI just runs the UI threads, but instead of an audio thread, we have a network thread that reads messages from the TCP socket and throws them on the FIFO.
Running the GUI in process would not only remove all the networking overhead, it would also allow to integrate custom UI elements (e.g. an openGL visualization of an ambisonic field). This would be a real game changer! Some externals, like FluoCoMa, are already struggling with Pd's limited GUI abilities. It would also massively simplify VST plugin hosting.
Christof
Well, to quote out of order:
"... for all built-in objects the core shouldn't have to tell the GUI how to draw it."
Well, I think that is a fundamental point on which you and I disagree. I tried once with Max/FTS (19890-1994 or so) to do precisely that and the problems of keeping the graphical layer and the real-time layer in sync ended up overwhelming. In particular, the graphcal layer had to wait while the real-time layer verified whether object creation succeeded or not which made the loading of a patch from file impossibly slow, unless the GUI layer had its own instance of Pd running right inside it in parallel with the real one. And that - keeping parallel copies of the same complex data structure in sync as it was changed from both sides - was also too much to manage.
I did float (a couple of years ago?) the idea of simply having one process with a GUI thread. Iohannes quickly warned me that that would invalidate a Pd variant he was working on - I forget what exactly. So I dropped that idea.
The winning feature of my proposal is that it can be done without disturbing the existing Pd at all. I could even add a gtk subdir to the Pd source tree and simultaneously maintain both GTL and TK versions for years while the kinks get worked out of the GTK one.
"... Why did you pick GTK specifically? What is the 2D canvas implementation like?"
My solution doesn't use the GTK canvas - it uses Cairo directly. OTOH it does redraw the entire drawing area offscreen - there's no region-invalidation as there was with the original Max (1988). This could be an efficiency problem, but it wouldn't be hard to put region-invalidation back in if indeed it turns out to be an issue.
OTOH I don't know whether Cairo will prove to be efficient enough for our purposes.
And... as to GTK4 versus QT, I can't see much reason to prefer one over the other, although I got a bad impression of QT after seeing what happened to LXDE when they migrated it to LXQT. The result was just... ugly. I also much refer GTK4's licensing --- it's hard open source as opposed to QT's attempting to take both sides on the issue. In my experience the hard-open-source projects such as linux or indeed pd itself tend to outlast the sort-of-open-source ones.
Anyway, I'm not sold on this way of doing things - I only put a week into it so far and have to tend to other stuff for this coming week, so there's time to think about all this.
cheers
Miller
On 30.09.2024 09:43, Miller Puckette wrote:
Well, to quote out of order:
"... for all built-in objects the core shouldn't have to tell the GUI how to draw it."
Well, I think that is a fundamental point on which you and I disagree. I tried once with Max/FTS (19890-1994 or so) to do precisely that and the problems of keeping the graphical layer and the real-time layer in sync ended up overwhelming. In particular, the graphcal layer had to wait while the real-time layer verified whether object creation succeeded or not which made the loading of a patch from file impossibly slow, unless the GUI layer had its own instance of Pd running right inside it in parallel with the real one. And that
- keeping parallel copies of the same complex data structure in sync
as it was changed from both sides - was also too much to manage.
I'm not sure I understand. Why would you need to wait for the UI to be in sync? What is the difference between
a. sending "draw X, Y, Z" to the UI
b. send "draw W" to the UI, which in turns draws "X, Y, Z"
You just shift the responsibility, but there is no fundamental difference. Please have a look at the linked draft PR form IOhannes! I've already linked the example for "bang" (https://github.com/pure-data/pure-data/pull/1765/files#diff-08294559d6a971f7...). Look at how many drawing commands we're currently sending to the UI for such a simple object! With the draft PR we would only send 1/10th of the commands even for the most simple objects. For more complex objects, like VU meter, it can be orders of magnitude.
But it's not only about the drawing commands itself. Sending commands like "draw a line", etc., mandates that the object is constructed of individual primitives on a canvas. But in a framework like Qt a built-in Pd object can just be a single widget (which knows how to draw itself). Of course, having one widget in a canvas is much more efficient than having dozens of individual geometric primitives!
I did float (a couple of years ago?) the idea of simply having one process with a GUI thread. Iohannes quickly warned me that that would invalidate a Pd variant he was working on - I forget what exactly. So I dropped that idea.
I would be curious to know about IOhannes' objections. I definitely think you were right back then :)
The winning feature of my proposal is that it can be done without disturbing the existing Pd at all. I could even add a gtk subdir to the Pd source tree and simultaneously maintain both GTL and TK versions for years while the kinks get worked out of the GTK one.
"... Why did you pick GTK specifically? What is the 2D canvas implementation like?"
My solution doesn't use the GTK canvas - it uses Cairo directly. OTOH it does redraw the entire drawing area offscreen - there's no region-invalidation as there was with the original Max (1988). This could be an efficiency problem, but it wouldn't be hard to put region-invalidation back in if indeed it turns out to be an issue.
I think region-invalidation will be absolutely crucial, especially for complex GOP GUIs.
OTOH I don't know whether Cairo will prove to be efficient enough for our purposes.
And... as to GTK4 versus QT, I can't see much reason to prefer one over the other, although I got a bad impression of QT after seeing what happened to LXDE when they migrated it to LXQT. The result was just... ugly. I also much refer GTK4's licensing --- it's hard open source as opposed to QT's attempting to take both sides on the issue. In my experience the hard-open-source projects such as linux or indeed pd itself tend to outlast the sort-of-open-source ones.
IMO Qt looks pretty great and it does a good job of emulating the individual platforms' native look. Have a look at SuperCollider's UI! I wouldn't call it ugly. It's just a matter of styling. It would be easy to recreate the current minimalistic Pd look.
I agree that GTK's licensing policy is more attractive. On the other hand, SuperCollider has been doing fine with Qt for quite some time now. I have to say that I don't have first-hand experience with GTK, so I can't really compare the two. I just had very good experiences with Qt building complex UIs.
Anyway, I'm not sold on this way of doing things - I only put a week into it so far and have to tend to other stuff for this coming week, so there's time to think about all this.
cheers
Miller
pd-dev@lists.iem.at - the Pd developers' mailinglist https://lists.iem.at/hyperkitty/list/pd-dev@lists.iem.at/message/RLRCVHGFFIX...
Another question I have: how is zooming implemented? That is one of the biggest pain points of the Tcl/Tk canvas.
In Qt you can transform the whole canvas view with simple function calls. For example, to zoom the canvas you just have to call the "scale" method: https://doc.qt.io/qt-6/qgraphicsview.html#scale.
(I have recently written an editor for my 2D game engine and it lets me zoom in and out of the tile map seemlessly. The tile map itself can easily consist of ten-thousands of objects and performance.)
Basically, what I want to say is: we need to carefully compare the performance characteristics of different UI frameworks, otherwise we may end up in a dead-end street.
---
Side note: another neat feature of the Qt canvas is that it's split into "model" (QGraphicsScene) and "view" (QGraphicsView). This allows for cool things like having multiple independent views into the same canvas. For example, you could split the window to show differenct sections of the same patch, similar to how a code editor can show multiple sections of the same source file.
On 30.09.2024 10:30, Christof Ressi wrote:
On 30.09.2024 09:43, Miller Puckette wrote:
Well, to quote out of order:
"... for all built-in objects the core shouldn't have to tell the GUI how to draw it."
Well, I think that is a fundamental point on which you and I disagree. I tried once with Max/FTS (19890-1994 or so) to do precisely that and the problems of keeping the graphical layer and the real-time layer in sync ended up overwhelming. In particular, the graphcal layer had to wait while the real-time layer verified whether object creation succeeded or not which made the loading of a patch from file impossibly slow, unless the GUI layer had its own instance of Pd running right inside it in parallel with the real one. And that - keeping parallel copies of the same complex data structure in sync as it was changed from both sides - was also too much to manage.
I'm not sure I understand. Why would you need to wait for the UI to be in sync? What is the difference between
a. sending "draw X, Y, Z" to the UI
b. send "draw W" to the UI, which in turns draws "X, Y, Z"
You just shift the responsibility, but there is no fundamental difference. Please have a look at the linked draft PR form IOhannes! I've already linked the example for "bang" (https://github.com/pure-data/pure-data/pull/1765/files#diff-08294559d6a971f7...). Look at how many drawing commands we're currently sending to the UI for such a simple object! With the draft PR we would only send 1/10th of the commands even for the most simple objects. For more complex objects, like VU meter, it can be orders of magnitude.
But it's not only about the drawing commands itself. Sending commands like "draw a line", etc., mandates that the object is constructed of individual primitives on a canvas. But in a framework like Qt a built-in Pd object can just be a single widget (which knows how to draw itself). Of course, having one widget in a canvas is much more efficient than having dozens of individual geometric primitives!
I did float (a couple of years ago?) the idea of simply having one process with a GUI thread. Iohannes quickly warned me that that would invalidate a Pd variant he was working on - I forget what exactly. So I dropped that idea.
I would be curious to know about IOhannes' objections. I definitely think you were right back then :)
The winning feature of my proposal is that it can be done without disturbing the existing Pd at all. I could even add a gtk subdir to the Pd source tree and simultaneously maintain both GTL and TK versions for years while the kinks get worked out of the GTK one.
"... Why did you pick GTK specifically? What is the 2D canvas implementation like?"
My solution doesn't use the GTK canvas - it uses Cairo directly. OTOH it does redraw the entire drawing area offscreen - there's no region-invalidation as there was with the original Max (1988). This could be an efficiency problem, but it wouldn't be hard to put region-invalidation back in if indeed it turns out to be an issue.
I think region-invalidation will be absolutely crucial, especially for complex GOP GUIs.
OTOH I don't know whether Cairo will prove to be efficient enough for our purposes.
And... as to GTK4 versus QT, I can't see much reason to prefer one over the other, although I got a bad impression of QT after seeing what happened to LXDE when they migrated it to LXQT. The result was just... ugly. I also much refer GTK4's licensing --- it's hard open source as opposed to QT's attempting to take both sides on the issue. In my experience the hard-open-source projects such as linux or indeed pd itself tend to outlast the sort-of-open-source ones.
IMO Qt looks pretty great and it does a good job of emulating the individual platforms' native look. Have a look at SuperCollider's UI! I wouldn't call it ugly. It's just a matter of styling. It would be easy to recreate the current minimalistic Pd look.
I agree that GTK's licensing policy is more attractive. On the other hand, SuperCollider has been doing fine with Qt for quite some time now. I have to say that I don't have first-hand experience with GTK, so I can't really compare the two. I just had very good experiences with Qt building complex UIs.
Anyway, I'm not sold on this way of doing things - I only put a week into it so far and have to tend to other stuff for this coming week, so there's time to think about all this.
cheers
Miller
pd-dev@lists.iem.at - the Pd developers' mailinglist https://lists.iem.at/hyperkitty/list/pd-dev@lists.iem.at/message/RLRCVHGFFIX...
pd-dev@lists.iem.at - the Pd developers' mailinglist https://lists.iem.at/hyperkitty/list/pd-dev@lists.iem.at/message/MCOBZHZPHPH...
going back to an earlier question, which I think is a (or the) central one...
On 9/30/24 10:30 AM, Christof Ressi wrote:
On 30.09.2024 09:43, Miller Puckette wrote:
Well, to quote out of order:
"... for all built-in objects the core shouldn't have to tell the GUI how to draw it."
Well, I think that is a fundamental point on which you and I disagree. I tried once with Max/FTS (19890-1994 or so) to do precisely that and the problems of keeping the graphical layer and the real-time layer in sync ended up overwhelming. In particular, the graphcal layer had to wait while the real-time layer verified whether object creation succeeded or not which made the loading of a patch from file impossibly slow, unless the GUI layer had its own instance of Pd running right inside it in parallel with the real one. And that - keeping parallel copies of the same complex data structure in sync as it was changed from both sides - was also too much to manage.
I'm not sure I understand. Why would you need to wait for the UI to be in sync? What is the difference between
a. sending "draw X, Y, Z" to the UI
b. send "draw W" to the UI, which in turns draws "X, Y, Z"
You just shift the responsibility, but there is no fundamental difference. Please have a look at the linked draft PR form IOhannes! I've already linked the example for "bang" (https://urldefense.com/v3/__https://github.com/pure-data/pure-data/pull/1765... ). Look at how many drawing commands we're currently sending to the UI for such a simple object! With the draft PR we would only send 1/10th of the commands even for the most simple objects. For more complex objects, like VU meter, it can be orders of magnitude.
But it's not only about the drawing commands itself. Sending commands like "draw a line", etc., mandates that the object is constructed of individual primitives on a canvas. But in a framework like Qt a built-in Pd object can just be a single widget (which knows how to draw itself). Of course, having one widget in a canvas is much more efficient than having dozens of individual geometric primitives!
Suppose we replace "draw X, Y,Z" with "draw button". I think this then spins out in either of two possible ways:
(1) the "button" widget on the GUI side now takes care of mouse-hit detection and making itself flash (and eventually widgets with text can grab focus, handle copy/paste, etc). In this case the GUI widget has to maintain a connection with its corresponding object in Pd. This gets very complicated when, for instance, changing text causes inlets or outlets to appear, which perhaps on the Pd side the text is getting hammered by messages from elsewhere at the same time. Distributed database management, anyone?
(2) it's just a drawing with a tag, not an active widget; perhaps mouse hit detection is done in the GUI but everything else in Pd. In this case it's not a big enough change to make much difference, except for this noisome one: "GUI externals" such as the knob now have to load dynamic libraries into two programs, instead of just one.
Depending on which scenario we want to consider (or perhaps this is somehow a false choice) we can go into more detail about this...
cheers
M
Christof Ressi wrote:
As I outlined in a previous mail
OK, I get the point. Sorry I didn't read this part of your message in detail before.
Miller Puckette wrote:
either of two possible ways:
My feeling goes towards (1).
causes inlets or outlets to appear on the Pd side the text is getting hammered by messages from elsewhere at the same time
I'm sure solutions can be found...
this noisome one: "GUI externals" such as the knob now have to load dynamic libraries into two programs
About this: the new GUI layer of pdlua is just awesome, and IMO something to take into account for future GUI dev of Pd. It's a very powerful and elegant way to design custom GUIs.
Le lun. 30 sept. 2024 à 14:37, Miller Puckette mpuckette@cloud.ucsd.edu a écrit :
going back to an earlier question, which I think is a (or the) central one...
On 9/30/24 10:30 AM, Christof Ressi wrote:
On 30.09.2024 09:43, Miller Puckette wrote:
Well, to quote out of order:
"... for all built-in objects the core shouldn't have to tell the
GUI how to draw it."
Well, I think that is a fundamental point on which you and I disagree. I tried once with Max/FTS (19890-1994 or so) to do precisely that and the problems of keeping the graphical layer and the real-time layer in sync ended up overwhelming. In particular, the graphcal layer had to wait while the real-time layer verified whether object creation succeeded or not which made the loading of a patch from file impossibly slow, unless the GUI layer had its own instance of Pd running right inside it in parallel with the real one. And that - keeping parallel copies of the same complex data structure in sync as it was changed from both sides - was also too much to manage.
I'm not sure I understand. Why would you need to wait for the UI to be in sync? What is the difference between
a. sending "draw X, Y, Z" to the UI
b. send "draw W" to the UI, which in turns draws "X, Y, Z"
You just shift the responsibility, but there is no fundamental difference. Please have a look at the linked draft PR form IOhannes! I've already linked the example for "bang" (https://urldefense.com/v3/__https://github.com/pure-data/pure-data/pull/1765... ). Look at how many drawing commands we're currently sending to the UI for such a simple object! With the draft PR we would only send 1/10th of the commands even for the most simple objects. For more complex objects, like VU meter, it can be orders of magnitude.
But it's not only about the drawing commands itself. Sending commands like "draw a line", etc., mandates that the object is constructed of individual primitives on a canvas. But in a framework like Qt a built-in Pd object can just be a single widget (which knows how to draw itself). Of course, having one widget in a canvas is much more efficient than having dozens of individual geometric primitives!
Suppose we replace "draw X, Y,Z" with "draw button". I think this then spins out in either of two possible ways:
(1) the "button" widget on the GUI side now takes care of mouse-hit detection and making itself flash (and eventually widgets with text can grab focus, handle copy/paste, etc). In this case the GUI widget has to maintain a connection with its corresponding object in Pd. This gets very complicated when, for instance, changing text causes inlets or outlets to appear, which perhaps on the Pd side the text is getting hammered by messages from elsewhere at the same time. Distributed database management, anyone?
(2) it's just a drawing with a tag, not an active widget; perhaps mouse hit detection is done in the GUI but everything else in Pd. In this case it's not a big enough change to make much difference, except for this noisome one: "GUI externals" such as the knob now have to load dynamic libraries into two programs, instead of just one.
Depending on which scenario we want to consider (or perhaps this is somehow a false choice) we can go into more detail about this...
cheers
M
pd-dev@lists.iem.at - the Pd developers' mailinglist https://lists.iem.at/hyperkitty/list/pd-dev@lists.iem.at/message/6WFFUCOQCFN...
Suppose we replace "draw X, Y,Z" with "draw button". I think this then spins out in either of two possible ways:
(1) the "button" widget on the GUI side now takes care of mouse-hit detection and making itself flash (and eventually widgets with text can grab focus, handle copy/paste, etc). In this case the GUI widget has to maintain a connection with its corresponding object in Pd. This gets very complicated when, for instance, changing text causes inlets or outlets to appear, which perhaps on the Pd side the text is getting hammered by messages from elsewhere at the same time. Distributed database management, anyone?
(2) it's just a drawing with a tag, not an active widget; perhaps mouse hit detection is done in the GUI but everything else in Pd. In this case it's not a big enough change to make much difference, except for this noisome one: "GUI externals" such as the knob now have to load dynamic libraries into two programs, instead of just one.
Depending on which scenario we want to consider (or perhaps this is somehow a false choice) we can go into more detail about this...
These are important points! I think there are two separate concerns:
1. who is doing the mouse-hit-detection?
2. who initiates the state changes (e.g. flashing, selection)
For example, it would be possible to do the hit detection on the GUI, but still do the state changes on the core. For example, in IOhannes draft PR, the "bang" object has an "activate" message that is sent whenever the flash state changes: https://github.com/pure-data/pure-data/pull/1765/files#diff-08294559d6a971f7...
We could move such internal state changes to the GUI, but we don't have to if it only complicates things.
However, I would love to move the hit detection to the GUI! Note that some GUI frameworks already do hit detection for canvas items. (In Qt, graphic items in a QGraphicsScene can receive mouse events!) In this case, doing the hit detection on the core is just duplicate work. It is also rather expensive since the core only stores the objects in a linked list, without spatial indexing, so every mouse movement has to potentially iterate over hundreds or even thousands gobjects and do rectangle intersection tests until it finds a hit. This is not something that you would want to do on the audio thread :)
The same thing applies to selections. The GUI typically already knows which objects are selected, so we only need to send this information to the core.
If we do the hit detection on the GUI, you are right that we need to keep an association between GUI widget and gobject. I think we just need to have a hashtable of tag -> gobject on the core; when the core receives a mouse event, it looks up the tag in the hashtable and then dispatches the event to the corresponding object. If the tag is not found, it means that the object has been destroyed in flight and we can just ignore the event.
There's one slight problem: some objects need to know *where* the user clicked. E.g. a slider with steady-on-click needs to know the position to set the new value. This means that the core side has to maintain some knowledge about the graphical representation. This does not seem to much of a problem to me, but it's something to be aware of.
---
Now here's the big catch: what should we do with GUI externals?
Ad 1: externals could define a region that acts as the bounding rectangle and which can be filled with drawing commands. This way they can partipicate in hit detection on the GUI.
Ad 2: I think state changes for externals have to be handled on the core because the external has no access to the GUI features. It does not even know which GUI it runs in.
One idea I had was to provide the GUI features as API functions. E.g. pdgui_drawrect() to draw a rectangle or pdgui_delay() to start a timer, etc. These API functions have to be implemented by the GUI, the core would just delegate the calls to the GUI. The external would register a callback function that is called whenever the object needs to be redrawn. Also, the GUI external could register callbacks for mouse events and paintings
One problem I see is that not every GUI can export C functions. For example, this probably wouldn't work with a web browser GUI...
The easiest solution is to just keep state changes for external GUI objects on the core, i.e. the external needs to send raw drawing commands. As an upside, this would make it easier to update existing externals as they would just have to update the drawing commands. Of course, as I said, sending all these individual commands not only increases traffic, it also means that the GUI has to maintain individual graphical primitives instead of just a single widget.
Either way, we should provide a stable GUI/drawing API for externals. Currently, it's all unofficial.
Thanks to Antoine for mentioning pdlua! I will need to check it out. I have already seen people doing some very cool stuff with it. Maybe they already have the perfect solution :)
---
I think all of this needs quite a bit of planning and design. We already had an online meeting two or three years ago before we started the GUI refactoring process. I would suggest to have another meeting where we can talk through all the potential issues and get a feel for the overall design.
Anyway, I'm very excited that the GUI refactoring is moving forward!
Christof
cheers
M
pd-dev@lists.iem.at - the Pd developers' mailinglist https://lists.iem.at/hyperkitty/list/pd-dev@lists.iem.at/message/6WFFUCOQCFN...
On 9/30/24 09:43, Miller Puckette wrote:
I did float (a couple of years ago?) the idea of simply having one process with a GUI thread. Iohannes quickly warned me that that would invalidate a Pd variant he was working on - I forget what exactly. So I dropped that idea.
that was about collaboratively editing Pd patches ("Peer Data").
as christof pointed out, if we make the middleware (basically pdgui_vmess()¹ and sys_do_startgui()) pluggable (as we already do with the scheduler), this would not be a problem. (apart from me not having worked on Peer Data for years :-))
generally i very much like the idea of Pd-core not depending on any 3rd party framework (whether that would be TclTk, Qt, GTK, JUCE or whatever) directly. (so I do not have to install half the whole world OR re-compile if I want transfer a Pd binary to a headless system)
dgfamsdr IOhannes
¹ and currently sys_vgui(). eventually i would like to get rid of sys_vgui() altogether, but at the time of writing there are still a few invocations of sys_vgui() left in the core, which would also need to be replaced. yss_vgui() is also used by plenty of externals that communicate directly with the GUI, one would have to think what to do about them.
generally i very much like the idea of Pd-core not depending on any 3rd party framework (whether that would be TclTk, Qt, GTK, JUCE or whatever) directly. (so I do not have to install half the whole world OR re-compile if I want transfer a Pd binary to a headless system)
We'd just need a configure option that allows to build Pd without the GUI. That's also what SuperCollider does: there's an option for building sclang without Qt (e.g. for headless systems).
It's just like building Pd with our without JACK, for example.
dgfamsdr IOhannes
¹ and currently sys_vgui(). eventually i would like to get rid of sys_vgui() altogether, but at the time of writing there are still a few invocations of sys_vgui() left in the core, which would also need to be replaced. yss_vgui() is also used by plenty of externals that communicate directly with the GUI, one would have to think what to do about them.
pd-dev@lists.iem.at - the Pd developers' mailinglist https://lists.iem.at/hyperkitty/list/pd-dev@lists.iem.at/message/SRGWTIH2247...
On 9/30/24 10:59, Christof Ressi wrote:
generally i very much like the idea of Pd-core not depending on any 3rd party framework (whether that would be TclTk, Qt, GTK, JUCE or whatever) directly. (so I do not have to install half the whole world OR re-compile if I want transfer a Pd binary to a headless system)
We'd just need a configure option that allows to build Pd without the GUI. That's also what SuperCollider does: there's an option for building sclang without Qt (e.g. for headless systems).
It's just like building Pd with our without JACK, for example.
right. it's just like that. i have been lobbying to make the audio backends a runtime selection years ago.
gfdmasr IOhannes
On 30.09.2024 11:09, IOhannes m zmoelnig wrote:
On 9/30/24 10:59, Christof Ressi wrote:
generally i very much like the idea of Pd-core not depending on any 3rd party framework (whether that would be TclTk, Qt, GTK, JUCE or whatever) directly. (so I do not have to install half the whole world OR re-compile if I want transfer a Pd binary to a headless system)
We'd just need a configure option that allows to build Pd without the GUI. That's also what SuperCollider does: there's an option for building sclang without Qt (e.g. for headless systems).
It's just like building Pd with our without JACK, for example.
right. it's just like that. i have been lobbying to make the audio backends a runtime selection years ago.
? All I wanted to say is that users can decide to build Pd without JACK support, i.e. Pd does not *depend* on JACK. We can do the same with the GUI.
gfdmasr IOhannes
pd-dev@lists.iem.at - the Pd developers' mailinglist https://lists.iem.at/hyperkitty/list/pd-dev@lists.iem.at/message/ESMIAQ3Q4WK...
On 9/30/24 11:25, Christof Ressi wrote:
We'd just need a configure option that allows to build Pd without the GUI. That's also what SuperCollider does: there's an option for building sclang without Qt (e.g. for headless systems).
It's just like building Pd with our without JACK, for example.
right. it's just like that. i have been lobbying to make the audio backends a runtime selection years ago.
? All I wanted to say is that users can decide to build Pd without JACK support, i.e. Pd does not *depend* on JACK. We can do the same with the GUI.
the Pd sources do not depend on JACK. but once Pd has been compiled (with JACK), the binaries do depend on JACK. aka: if you do not have libjack installed (and your OS does not support weak linking), then Pd such a binary will not start.
or to turn it around: if i want to add a new audio backend to Pd (e.g. a native PipeWire backend; or some network audio driver like AOO), i must convince the BDFL to include my code into Pd core. if audio backends were decided runtime (based on some "audio backend external" i could just provide it via deken.
fdsmt IOhannes
On 30.09.2024 11:33, IOhannes m zmoelnig wrote:
On 9/30/24 11:25, Christof Ressi wrote:
We'd just need a configure option that allows to build Pd without the GUI. That's also what SuperCollider does: there's an option for building sclang without Qt (e.g. for headless systems).
It's just like building Pd with our without JACK, for example.
right. it's just like that. i have been lobbying to make the audio backends a runtime selection years ago.
? All I wanted to say is that users can decide to build Pd without JACK support, i.e. Pd does not *depend* on JACK. We can do the same with the GUI.
the Pd sources do not depend on JACK. but once Pd has been compiled (with JACK), the binaries do depend on JACK. aka: if you do not have libjack installed (and your OS does not support weak linking), then Pd such a binary will not start.
or to turn it around: if i want to add a new audio backend to Pd (e.g. a native PipeWire backend; or some network audio driver like AOO), i must convince the BDFL to include my code into Pd core. if audio backends were decided runtime (based on some "audio backend external" i could just provide it via deken.
Ah, now I see what you mean. Of course, the audio API can already be selected at runtime, hence my confusion. What you are proposing is really a plugin mechanism - which is a pretty cool idea!
fdsmt IOhannes
pd-dev@lists.iem.at - the Pd developers' mailinglist https://lists.iem.at/hyperkitty/list/pd-dev@lists.iem.at/message/N32DLXSNG5K...
Having the GUI running on a separate process has several advantages: - no additional dependency to the core, as IOhannes pointed out. - possible choice between several GUI apps - possibility to run the GUI from another computer, and/or to launch the GUI app alone and connect it dynamically to already running Pd/libpd instances.
Le lun. 30 sept. 2024 à 11:45, Christof Ressi info@christofressi.com a écrit :
On 30.09.2024 11:33, IOhannes m zmoelnig wrote:
On 9/30/24 11:25, Christof Ressi wrote:
We'd just need a configure option that allows to build Pd without the GUI. That's also what SuperCollider does: there's an option for building sclang without Qt (e.g. for headless systems).
It's just like building Pd with our without JACK, for example.
right. it's just like that. i have been lobbying to make the audio backends a runtime selection years ago.
? All I wanted to say is that users can decide to build Pd without JACK support, i.e. Pd does not *depend* on JACK. We can do the same with the GUI.
the Pd sources do not depend on JACK. but once Pd has been compiled (with JACK), the binaries do depend on JACK. aka: if you do not have libjack installed (and your OS does not support weak linking), then Pd such a binary will not start.
or to turn it around: if i want to add a new audio backend to Pd (e.g. a native PipeWire backend; or some network audio driver like AOO), i must convince the BDFL to include my code into Pd core. if audio backends were decided runtime (based on some "audio backend external" i could just provide it via deken.
Ah, now I see what you mean. Of course, the audio API can already be selected at runtime, hence my confusion. What you are proposing is really a plugin mechanism - which is a pretty cool idea!
fdsmt IOhannes
pd-dev@lists.iem.at - the Pd developers' mailinglist https://lists.iem.at/hyperkitty/list/pd-dev@lists.iem.at/message/N32DLXSNG5K...
pd-dev@lists.iem.at - the Pd developers' mailinglist https://lists.iem.at/hyperkitty/list/pd-dev@lists.iem.at/message/ZSQHFJYD4L2...
On 30.09.2024 13:55, Antoine Rousseau wrote:
Having the GUI running on a separate process has several advantages:
- no additional dependency to the core, as IOhannes pointed out.
As I said, you can achieve the same thing with an in-process GUI. The GUI can even be implemented as a plugin, i.e. loaded at runtime.
- possible choice between several GUI apps
Same as above.
- possibility to run the GUI from another computer, and/or to launch
the GUI app alone and connect it dynamically to already running Pd/libpd instances.
As I outlined in a previous mail, this can be done on top of the in-process GUI. See https://lists.iem.at/hyperkitty/list/pd-dev@lists.iem.at/message/SQGTXOKHMPI...
While all your points are valid, none of these *require* an out-of-process GUI.
Le lun. 30 sept. 2024 à 11:45, Christof Ressi info@christofressi.com a écrit :
On 30.09.2024 11:33, IOhannes m zmoelnig wrote:
On 9/30/24 11:25, Christof Ressi wrote:
We'd just need a configure option that allows to build Pd without the GUI. That's also what SuperCollider does: there's an option for building sclang without Qt (e.g. for headless systems).
It's just like building Pd with our without JACK, for example.
right. it's just like that. i have been lobbying to make the audio backends a runtime selection years ago.
? All I wanted to say is that users can decide to build Pd without JACK support, i.e. Pd does not *depend* on JACK. We can do the same with the GUI.
the Pd sources do not depend on JACK. but once Pd has been compiled (with JACK), the binaries do depend on JACK. aka: if you do not have libjack installed (and your OS does not support weak linking), then Pd such a binary will not start.
or to turn it around: if i want to add a new audio backend to Pd (e.g. a native PipeWire backend; or some network audio driver like AOO), i must convince the BDFL to include my code into Pd core. if audio backends were decided runtime (based on some "audio backend external" i could just provide it via deken.
Ah, now I see what you mean. Of course, the audio API can already be selected at runtime, hence my confusion. What you are proposing is really a plugin mechanism - which is a pretty cool idea!
fdsmt IOhannes
pd-dev@lists.iem.at - the Pd developers' mailinglist https://lists.iem.at/hyperkitty/list/pd-dev@lists.iem.at/message/N32DLXSNG5K...
pd-dev@lists.iem.at - the Pd developers' mailinglist https://lists.iem.at/hyperkitty/list/pd-dev@lists.iem.at/message/ZSQHFJYD4L2...