<html><body>Hello openjfx-dev,<br><br>First of all I want thank you all for an amazing work you are doing.<br>I'm excited about new features comming to FX and in general I do enjoy<br>to work with the framework.<br><br>I would like to ask for help.<br>I'm trying get more experience with new java FFM API. The best way<br>how to learn new API is by using is in a project. My goal is to somehow<br>have the ability to show on a taskbar progress of some long running task.<br>As far as I know, there is no "native" support of this in JavaFX.<br>There are some libraries like <br>"https://github.com/Dansoftowner/FXTaskbarProgressBar" which serves the<br>purpose, but only for Windows. And it is using the "old" JNI.<br><br>After a short research, I found a simple library in go<br>https://github.com/bibelin/taskbar. It got inspired by this library<br>and tried to "convert" it to JavaFX.<br><br>First I used jextract to get java bindings to native library calls:<br>jextract --output target/generated-sources/jextract -t "taskbar_test.gen" --include-function "XOpenDisplay" --include-function "XChangeProperty" --include-function "XFlush" --include-function "XCloseDisplay" /usr/include/X11/Xlib.h<br><br>Then I created a simple application to simulate long running process<br>where I try to update progress on taskbar by calling method <br>"XChangeProperty" which I found in documentation of X11:<br>https://www.x.org/releases/X11R7.7/doc/libX11/libX11/libX11.html#XChangeProperty<br><br>Unfortunately this does not work. The program does not crash,<br>task is running on background, but no update on taskbar is happening.<br><br>Here is the code I created:<br>package taskbar_test;<br><br>import com.sun.glass.ui.Window;<br>import javafx.application.Application;<br>import javafx.concurrent.Task;<br>import javafx.scene.Scene;<br>import javafx.scene.control.Button;<br>import javafx.scene.layout.VBox;<br>import javafx.stage.Stage;<br>import taskbar_test.gen.Xlib_h;<br><br>import java.lang.foreign.Arena;<br>import java.lang.foreign.MemorySegment;<br>import java.lang.foreign.ValueLayout;<br><br><br>public class AppLinuxXlib extends Application {<br><br>    @Override<br>    public void start(Stage primaryStage) {<br>        Button startButton = new Button("Start Long Running Task");<br><br>        startButton.setOnAction(event -> {<br>            final long rawHandle = Window.getWindows().getFirst().getRawHandle();<br>            System.out.println(rawHandle);<br>            // Create a long-running task<br>            Task<Void> longTask = new Task<>() {<br>                @Override<br>                protected Void call() throws Exception {<br>                    System.out.println("Started");<br><br>                    try (var arena = Arena.ofConfined()) {<br>                        var NET_WM_XAPP_PROGRESS = arena.allocateFrom("NET_WM_XAPP_PROGRESS");<br>//                        var NET_WM_XAPP_PROGRESS_PULSE = arena.allocateFrom("NET_WM_XAPP_PROGRESS_PULSE");<br><br>                        MemorySegment x11Session = Xlib_h.XOpenDisplay(MemorySegment.NULL);<br>                        System.out.println(x11Session);<br><br>                        // Prepare the progress data<br>                        MemorySegment initData = arena.allocateFrom(ValueLayout.JAVA_INT, 0);<br>                        Xlib_h.XChangeProperty(x11Session,                    // display<br>                                MemorySegment.ofAddress(rawHandle).address(), // window<br>                                NET_WM_XAPP_PROGRESS.address(),               // property<br>                                6,                                            // type<br>                                32,                                           // format<br>                                0,                                            // mode PropModeReplace=0<br>                                initData,                                     // data<br>                                1);                                           // nelements<br>                        Xlib_h.XFlush(x11Session);<br><br>                        System.out.println("Countdown started");<br><br>                        // Set the taskbar progress<br>                        for (int i = 0; i <= 100; i+=20) {<br>                            // Simulate work<br>                            Thread.sleep(500);<br>                            System.out.println(i);<br>                            MemorySegment progressData = arena.allocateFrom(ValueLayout.JAVA_INT, i);<br>                            // Update taskbar progress<br>                            // https://www.x.org/releases/X11R7.7/doc/libX11/libX11/libX11.html#XChangeProperty<br>                            Xlib_h.XChangeProperty(x11Session,                    // display<br>                                    MemorySegment.ofAddress(rawHandle).address(), // window<br>                                    NET_WM_XAPP_PROGRESS.address(),               // property<br>                                    6,                                            // type<br>                                    32,                                           // format<br>                                    0,                                            // mode PropModeReplace=0<br>                                    progressData,                                // data<br>                                    1);                                           // nelements<br>                            Xlib_h.XFlush(x11Session);<br>                        }<br>                        System.out.println("Finished");<br>                        Xlib_h.XCloseDisplay(x11Session);<br><br>                    } catch (Throwable ex) {<br>                        ex.printStackTrace();<br>                    }<br>                    return null;<br>                }<br>            };<br><br>            // Start the task in a new thread<br>            new Thread(longTask).start();<br>        });<br><br>        VBox vbox = new VBox(10, startButton);<br>        Scene scene = new Scene(vbox, 300, 200);<br>        primaryStage.setScene(scene);<br>        primaryStage.setTitle("Taskbar Progress Example Linux");<br>        primaryStage.show();<br>    }<br><br>    public static void main(String[] args) {<br>        launch(args);<br>    }<br>}<br><br>Can someone show me what am I doing wrong and maybe point me to the correct<br>direction with how to make the implementation work?<br><br>Thank you very much.<br><br>Best regards,<br>Petr Štechmüller<br><br></body></html>