On Fri, 1 Nov 2024 23:38:52 GMT, Michael Strauß <mstra...@openjdk.org> wrote:
>> This PR is a new take on a highly requested feature: JavaFX controls in the >> header bar (see also #594 for an earlier iteration). >> >> This is a feature with many possible ways to skin the cat, and it has taken >> quite a bit of effort to come up with a good user model. In contrast to the >> previous iteration, the focus has shifted from providing an entirely >> undecorated window to providing a window with a user-configurable header bar. >> >> The customizable header bar is a new layout container: >> `javafx.scene.layout.HeaderBar`. It has three areas that accept child nodes: >> leading, center, and trailing. `HeaderBar` also automatically adjusts for >> the placement of the default window buttons (minimize, maximize, close) on >> the left or right side of the window. >> >> The customizable header bar is combined with a new `EXTENDED` stage style, >> which extends the client area into the header bar area. The new extended >> stage style is supported on Windows, macOS, and Linux. For platforms that >> don't support this stage style, it automatically downgrades to `DECORATED`. >> >> This is how it looks like on each of the three operating systems: >> >>  >> >> The window buttons (minimize, maximize, close) are provided by JavaFX, not >> by the application developer. This makes it easier to get basic window >> functionality without recreating the entirety of the window controls for all >> platforms. >> >> ## Usage >> This is a minimal example that uses a custom header bar with a `TextField` >> in the center area. `HeaderBar` is usually placed in the top area of a >> `BorderPane` root container: >> >> public class MyApp extends Application { >> @Override >> public void start(Stage stage) { >> var headerBar = new HeaderBar(); >> headerBar.setCenter(new TextField()); >> >> var root = new BorderPane(); >> root.setTop(headerBar); >> >> stage.setScene(new Scene(root)); >> stage.initStyle(StageStyle.EXTENDED); >> stage.show(); >> } >> } >> >> To learn more about the details of the API, refer to the documentation of >> `StageStyle.EXTENDED` and `HeaderBar`. >> >> ## Platform integration >> The implementation varies per platform, and ranges from pretty easy to quite >> involved: >> 1. **macOS**: The window buttons are provided by macOS, we just leave an >> empty area where the window buttons will appear. The client area is extended >> to cover the entire window by setting the `NSW... > > Michael Strauß has updated the pull request with a new target base due to a > merge or a rebase. The pull request now contains 23 commits: > > - Merge branch 'master' into feature/extended-window > - Merge branch 'master' into feature/extended-window > - macOS: dynamically adapt toolbar style to headerbar height > - fix header bar height flicker > - NPE > - fix peer access outside of synchronizer > - improve title text documentation > - macOS: hide window title > - better documentation > - set minHeight to native height of title bar > - ... and 13 more: https://git.openjdk.org/jfx/compare/58cd76a8...9b63892d I'm not sure if it's feasible, but having a `GtkOverlay` seems to work on a basic app paintable C app: #include <gtk/gtk.h> static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr) { cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); cairo_paint(cr); return FALSE; } static void create_overlay(GtkWidget *window) { GtkWidget *overlay; GtkWidget *hb; overlay = gtk_overlay_new(); gtk_container_add(GTK_CONTAINER(window), overlay); hb = gtk_header_bar_new(); gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(hb), TRUE); gtk_header_bar_set_has_subtitle(GTK_HEADER_BAR(hb), FALSE); gtk_header_bar_set_custom_title(GTK_HEADER_BAR(hb), NULL); gtk_overlay_add_overlay(GTK_OVERLAY(overlay), hb); gtk_widget_set_valign(hb, GTK_ALIGN_START); gtk_widget_set_halign(hb, GTK_ALIGN_END); } int main(int argc, char *argv[]) { GtkWidget *window; // Initialize GTK gtk_init(&argc, &argv); GtkCssProvider *css_provider = gtk_css_provider_new(); gtk_css_provider_load_from_data(css_provider, "headerbar {" " background-color: rgba(255, 255, 255, 0.0);" "}", -1, NULL); gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), GTK_STYLE_PROVIDER(css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Test"); gtk_window_set_decorated(GTK_WINDOW(window), FALSE); gtk_window_set_default_size(GTK_WINDOW(window), 400, 300); gtk_widget_set_app_paintable(window, TRUE); g_signal_connect(G_OBJECT(window), "draw", G_CALLBACK(on_draw_event), NULL); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); create_overlay(window); gtk_widget_show_all(window); gtk_main(); return 0; } Gtk4 even has [WindowControls](https://docs.gtk.org/gtk4/class.WindowControls.html). I started to play with the CSS to make it transparent, but it does not seem much straightforward, but possible. Running the program with `GTK_DEBUG=interactive` makes it easier. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1605#issuecomment-2454756382