cgtk4

How to change background & color of GtkPopoverMenu(GMenuModel) with css?


I am trying to change the background and color of a gtk4 popover context menu with CSS. Below is the demo script of how I tried it.

Although the foreground color effect is working fine, the background color is not working properly.

What needs to be changed to make it work? How this can be done, Can anyone check it please?

Thank you in advance.

#include <gtk/gtk.h>
static void
fullscreen_changed(GSimpleAction *action, GVariant *value, gpointer win) {
  if (g_variant_get_boolean (value))
    gtk_window_maximize (GTK_WINDOW (win));
  else
    gtk_window_unmaximize (GTK_WINDOW (win));
  g_simple_action_set_state (action, value);
}

static void
quit_activated(GSimpleAction *action, GVariant *parameter, gpointer app)
{
  g_application_quit (G_APPLICATION(app));
}

static void
app_activate (GApplication *app, gpointer user_data) {
  GtkWidget *win = gtk_application_window_new (GTK_APPLICATION (app));
  gtk_window_set_title (GTK_WINDOW (win), "menu");
  gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);

  GtkWidget *lb = gtk_label_new (NULL);
  gtk_widget_set_name (lb, "lb"); /* the name is used by CSS Selector */
  gtk_window_set_child (GTK_WINDOW (win), lb);

  GSimpleAction *act_fullscreen = g_simple_action_new_stateful ("fullscreen", NULL, g_variant_new_boolean (FALSE));
  GSimpleAction *act_quit = g_simple_action_new ("quit", NULL);

  GMenu *menubar = g_menu_new ();
  GMenu *menu = g_menu_new ();

  GMenu *section1 = g_menu_new ();
  GMenu *section2 = g_menu_new ();

  GMenuItem *menu_item_fullscreen = g_menu_item_new ("Full Screen", "win.fullscreen");
  GMenuItem *menu_item_quit = g_menu_item_new ("Quit", "app.quit");
  g_signal_connect (act_fullscreen, "change-state", G_CALLBACK (fullscreen_changed), win);
  g_signal_connect (act_quit, "activate", G_CALLBACK (quit_activated), app);

  g_action_map_add_action (G_ACTION_MAP (win), G_ACTION (act_fullscreen));
  g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (act_quit));

  g_menu_append_item (section1, menu_item_fullscreen);
  g_menu_append_item (section2, menu_item_quit);

  g_object_unref (menu_item_fullscreen);
  g_object_unref (menu_item_quit);

  g_menu_append_section (menu, NULL, G_MENU_MODEL (section1));
  g_menu_append_section (menu, NULL, G_MENU_MODEL (section2));
  g_menu_append_submenu (menubar, "Menu", G_MENU_MODEL (menu));

  gtk_application_set_menubar (GTK_APPLICATION (app), G_MENU_MODEL (menubar));
  gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (win), TRUE);

  static GtkCssProvider *provider;
  provider = gtk_css_provider_new ();
  GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (win));
  gtk_css_provider_load_from_string (provider, 
                          "label#lb {background-color: blue; }"
                          "popover *{ color: red; }"
                          "popover.menu{ background: rgba(0, 1, 1, 0.4); }\n" );

  gtk_style_context_add_provider_for_display (display, GTK_STYLE_PROVIDER (provider),
                                        GTK_STYLE_PROVIDER_PRIORITY_USER);
  gtk_window_present (GTK_WINDOW (win));
}

int
main (int argc, char **argv) {
  GtkApplication *app;
  int stat;
  app = gtk_application_new ("com.gtk4.demo.menu", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
  stat =g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);
  return stat;
}

Solution

  • with Ubuntu it works as follows:

     gtk_css_provider_load_from_string (provider,
                              "label#lb {background-color: blue; }"
                              "popover *{ color: red; background: yellow }");
    

    Another interesting variant is:

     gtk_css_provider_load_from_string (provider,
                              "label#lb {background-color: blue; }"
                              "popover contents {color:green; background:gray;}"
                              "popover contents:hover{color: red; background: yellow;}");
    

    Have fun experimenting.