Issue with GtkSearchBar

Hi there.
Here is my problem. I’m learning gtk and started to create a simple app. I wanted to place the search entry right in the corner of the window. I placed search entry inside search bar and wrote gtk_widget_set_halign(search_bar, GTK_ALIGN_START), but for some reason there was a gap between search bar and edge of the window. I tried to solve this problem by using css, where i set margins and paddings to 0 but it didn’t help. I tried g_object_set(search_bar, “margin”, 0, NULL) and other functions. No effect. I found out, that the problem is in searchbar, because if I place search entry directly inside toplevel window, it is placed so close to the edge as possible (I.e. no gaps).
I couldn’t find the answer in gtk docs or anywhere else. So, what’s the solution? Just not to use search bar?
Here is some code:

int main (int argc, char * argv[])
{
  GtkWidget * mainwin;          //GTK_WINDOW
  GtkWidget * search_bar;         //GTK_SEARCH_BAR
  GtkWidget * search_entry;         //GTK_SEARCH_ENTRY

  gtk_init(&argc, &argv);

  mainwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  search_bar = gtk_search_bar_new();
  search_entry = gtk_search_entry_new();

  gtk_window_set_default_size(GTK_WINDOW(mainwin), 900, 650);
  gtk_search_bar_set_search_mode(GTK_SEARCH_BAR(search_bar), TRUE);
  gtk_widget_set_halign(search_bar, GTK_ALIGN_START);

  gtk_container_add(GTK_CONTAINER(mainwin), search_bar);
  gtk_container_add(GTK_CONTAINER(search_bar), search_entry);

  gtk_widget_show_all(mainwin);

  gtk_main();

  return 0;
}

I appreciate any art of help

As you may have seen the GTK devs provide an example for GtkSearchBar:

https://gitlab.gnome.org/GNOME/gtk/blob/gtk-3-24/examples/search-bar.c

Have you already played with that one?

That example uses the GtkApplication style already, which is generally recommended for GTK3 and GTK4 apps.

Unfortunately I have to admit that I have no idea why there are so many calls of gtk_widget_show() in that example.

Yes, i have seen this example code. If I launch it as is I see only blank window. To make it visible I have to add this code line:
gtk_search_bar_set_search_mode(GTK_SEARCH_BAR(search_bar), TRUE);
This space around the SearchBar is also here. I made screenshot and counted the width of this margin. It is 6 px over and under the widget and 12 px on the left and right side. Setting margin and padding at 0px for everything still doesn’t help. Try this:

* {
     padding: 0px;
     margin: 0px;
   }

Setting all possible properties with the function g_object_set() to 0 also didn’t help.
I spent today a few hours again to find the property, that creates this gaps but the problem is still there. I have no idea how to solve it.

OK, I will try it also. But I don’t know GTK really well, so I have not much hope that I can really solve that issue. Will tell you more tomorrow.

1 Like

I just started with the latest GTK4 version. For me in the unmodified version the search entry pops up when I press some keys on my keyboard. Then I tried to modify the code to move the entry fully to the right, and indeed that widget has a grey border which does not allow to move it fully to the right. I will see how we can remove the border.

1 Like

Using the https://blog.gtk.org/2017/04/05/the-gtk-inspector/

I get the feeling that the GtkEntry has a border-spacing of 6 pixels. Will see If I can set it to 0 by CSS.

1 Like

Thank you for the link! I haven’t heard of it before. I turned on this mode and solved the problem very quickly.
Before that, when I tried to solve the problem using css, I set 1px border to every gtk_box. But in fact this border was not one pixel, but four. 6px space, 3px border, 6px space, 1px border. So I had a suggestion that the search entry is not directly in search bar, but there are several intermediate (hidden) containers. So it turned out. This debugging tool illustrated, that structure is like this GtkSearchBar -> GtkRevealer -> GtkBox -> GtkBox -> GtkSearchEntry, I looked at the properties of each of them and one of them has a border width of 6 pixels! Earlier I tried using the gtk_container_set_border_width() function, but it didn’t help, because this border owns not the search bar, but one of the intermediate containers. The problem is almost solved. The borders on the bottom and top disappeared, and on both sides was halved to 6 pixels. I will see tomorrow which of the child elements needs to be reset to zero too, but you helped me solve the problem!
p.s. Sorry for my English, if it was difficult to you to understand what i mean. It’s not my native language :slight_smile:

Fine that I could help you a bit. I have not much experience with gtk-inspector and CSS. I have also discovered the hidden box and tried with CSS like

char *data = “box {margin-right: 0px; padding-right: 0px;}”;

but it was not working really perfect for me. The reason may be that I tried it with GTK4. I was going to try a GTK3 version tomorrow, but when it nearly works for you then you may post your solution and some of the real GTK experts like Mr. Bassi may do the rest.

1 Like

I hope you had some success. For most of my tests with GTK3 the results where not as expected unfortunately. Generally I do not use own CSS but only use the defaults, but I have styled some labels some years ago just for fun. Now for the searchbar example, as paddings and margins are hard, I did test with font. In gtk-inspector we can type in CSS code and it modifies the app in real time. So I entered

label {font: 8px Sans;}

and the window title got a tiny font. But when I use that directly from my program window title does not change. Have no idea why currently, I guess I have to read all the CSS docs more carefully.

// https://gitlab.gnome.org/GNOME/gtk/blob/gtk-3-24/examples/search-bar.c
// gcc -o t t.c `pkg-config --libs --cflags gtk+-3.0`
#include <gtk/gtk.h>
static gboolean
window_key_press_event_cb (GtkWidget *window,
    GdkEvent *event,
    GtkSearchBar *search_bar)
{
  return gtk_search_bar_handle_event (search_bar, event);
}
static void
activate_cb (GtkApplication *app,
    gpointer user_data)
{
  GtkWidget *window;
  GtkWidget *search_bar;
  GtkWidget *box;
  GtkWidget *entry;
  GtkWidget *menu_button;
  window = gtk_application_window_new (app);
  gtk_widget_show (window);
  search_bar = gtk_search_bar_new ();
  gtk_container_add (GTK_CONTAINER (window), search_bar);
  gtk_widget_show (search_bar);
  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
  gtk_container_add (GTK_CONTAINER (search_bar), box);
  gtk_widget_show (box);
  entry = gtk_search_entry_new ();
  
  GtkCssProvider *cssProvider = gtk_css_provider_new();
  char *data = "label {font: 8px Sans;}";
  gtk_css_provider_load_from_data(cssProvider, data, -1, NULL);
  gtk_style_context_add_provider(gtk_widget_get_style_context(window),
                                   GTK_STYLE_PROVIDER(cssProvider),
                                   GTK_STYLE_PROVIDER_PRIORITY_USER);
  
  gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 0);
  gtk_widget_show (entry);
  menu_button = gtk_menu_button_new ();
  gtk_box_pack_start (GTK_BOX (box), menu_button, FALSE, FALSE, 0);
  gtk_widget_show (menu_button);
  gtk_search_bar_connect_entry (GTK_SEARCH_BAR (search_bar), GTK_ENTRY (entry));
  g_signal_connect (window, "key-press-event",
      G_CALLBACK (window_key_press_event_cb), search_bar);
}

gint
main (gint argc,
    gchar *argv[])
{
  GtkApplication *app;
  app = gtk_application_new ("org.gtk.Example.GtkSearchBar",
      G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate",
      G_CALLBACK (activate_cb), NULL);
  return g_application_run (G_APPLICATION (app), argc, argv);
}

Sorry, was really a stupid error. Of course for not directly accessible widgets one has to use
gtk_style_context_add_provider_for_screen() as shown in the stackoverflow example:

I was just plying with a Nim version and a plain entry widgets and the error was obvious. In the bloated C code it is hard for me to see what I am really doing and I expected the problem at fully wrong sources. Here is a working Nim code for an GtkEntry, I may play more with a GtkSearchBar later…

import gintro/[gtk, gdk, glib, gobject, gio]

proc appActivate(app: Application) =
  let window = newApplicationWindow(app)
  let entry = newEntry()
  let cssProvider = newCssProvider()
  let data = "entry {color: yellow; background: green;}"
  discard cssProvider.loadFromData(data)
  addProviderForScreen(getDefaultScreen(), cssProvider, STYLE_PROVIDER_PRIORITY_USER)
  window.add(entry)
  showAll(window)

proc main =
  let app = newApplication("org.gtk.example")
  connect(app, "activate", appActivate)
  discard run(app)

main()

##########################################################################
No more than 3 consecutive replies are allowed. Please edit your previous reply, or wait for someone to reply to you.
##########################################################################

I will give up. Setting margin and padding to zero does not really work for the searchbar. I assume that there are hardcoded margins involved. But what you can do is setting negative margin or padding for the entry. I did my tests for the left border, as that was simpler. You should be able to do it for the right side. The following C code has the entry close to the left window border:

// https://gitlab.gnome.org/GNOME/gtk/blob/gtk-3-24/examples/search-bar.c
// gcc -o t t.c `pkg-config --libs --cflags gtk+-3.0`
#include <gtk/gtk.h>
static gboolean
window_key_press_event_cb (GtkWidget *window,
    GdkEvent *event,
    GtkSearchBar *search_bar)
{
  return gtk_search_bar_handle_event (search_bar, event);
}
static void
activate_cb (GtkApplication *app,
    gpointer user_data)
{
  GtkWidget *window;
  GtkWidget *search_bar;
  GtkWidget *box;
  GtkWidget *entry;
  GtkWidget *menu_button;
  window = gtk_application_window_new (app);
  gtk_widget_show (window);
  search_bar = gtk_search_bar_new ();
  gtk_container_add (GTK_CONTAINER (window), search_bar);
  gtk_widget_show (search_bar);
  box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
  gtk_container_add (GTK_CONTAINER (search_bar), box);
  gtk_widget_show (box);
  entry = gtk_search_entry_new ();
  
  GtkCssProvider *cssProvider = gtk_css_provider_new();
  //char *data = "window {color: yellow; background: green;} window, decoration, searchbar, box, entry, image.left, button {margin-left: 0px; padding-left: 0px;}";
   //char *data = "window, decoration, searchbar, box, entry, image.left, button {margin-left: 0px; padding-left: 0px;}";
  //char *data = "* {margin-left: 0px; padding-left: 0px; border-left: 0px;}";
  char *data = "searchbar entry {margin-left: -8px; padding-left: 0px;}";
  gtk_css_provider_load_from_data(cssProvider, data, -1, NULL);
  gtk_style_context_add_provider_for_screen(gdk_screen_get_default(),
                               GTK_STYLE_PROVIDER(cssProvider),
                               GTK_STYLE_PROVIDER_PRIORITY_USER);

  gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 0);
  gtk_widget_show (entry);
  menu_button = gtk_menu_button_new ();
  gtk_box_pack_start (GTK_BOX (box), menu_button, FALSE, FALSE, 0);
  gtk_widget_show (menu_button);
  gtk_search_bar_connect_entry (GTK_SEARCH_BAR (search_bar), GTK_ENTRY (entry));
  g_signal_connect (window, "key-press-event",
      G_CALLBACK (window_key_press_event_cb), search_bar);
}

gint
main (gint argc,
    gchar *argv[])
{
  GtkApplication *app;
  app = gtk_application_new ("org.gtk.Example.GtkSearchBar",
      G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate",
      G_CALLBACK (activate_cb), NULL);
  return g_application_run (G_APPLICATION (app), argc, argv);
}

Sorry for not answering.
I really appreciate that you trying to help me.
Yesterday I continued to work on my own small project. I deleted this border, but not completely. They are now half the size (6 px left and right) and no border above and under. I can remove the rest with inspector by hiding internal boxes inside search bar. But I failed to do the same from inside my code. Here is the end result of my code:

int main (int argc, char * argv[])
{
  GtkWidget * mainwin;          //GTK_WINDOW
  GtkWidget * search_bar;         //GTK_SEARCH_BAR
  GtkWidget * search_entry;         //GTK_SEARCH_ENTRY

  gtk_init(&argc, &argv);

  mainwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  search_bar = gtk_search_bar_new();
  search_entry = gtk_search_entry_new();

  GtkCssProvider * css_provider = gtk_css_provider_new();
  GdkDisplay * display = gdk_display_get_default();
  GdkScreen * screen = gdk_display_get_default_screen(display);

  gtk_css_provider_load_from_path(GTK_CSS_PROVIDER(css_provider), "theme.css", NULL);
  gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER);

  //setting internal box border width to 0
  GtkWidget * hiddenBox = gtk_bin_get_child(GTK_BIN(gtk_bin_get_child(GTK_BIN(search_bar))));
  gtk_container_set_border_width(GTK_CONTAINER(hiddenBox), 0);

  gtk_window_set_default_size(GTK_WINDOW(mainwin), 900, 650);
  gtk_search_bar_set_search_mode(GTK_SEARCH_BAR(search_bar), TRUE);
  gtk_widget_set_halign(search_bar, GTK_ALIGN_START);

  gtk_container_add(GTK_CONTAINER(mainwin), search_bar);
  gtk_container_add(GTK_CONTAINER(search_bar), search_entry);

  gtk_widget_show_all(mainwin);

  gtk_main();

  return 0;
}

and theme.css

entry {
  border: 1px solid black;
}

because setting margin and padding to 0 doesn’t seem to change something.

So, because it is pretty difficult for me, to completely remove this border and I assume that changing internal properties is not a good idea, I will change my code by using regular container and not GtkSearchBar.
I move forward, I don’t want to get stuck by small visual imperfections. I have first of all to implement basic functionality of my app. My app will be a diary because I don’t like the one, I’m currently using.
For that i need to learn how to interact with files. Yesterday I started to read tutorial about GIO but I found it not obvious and not easy to use. Maybe I will use standard POSIX library (stdio and others).
Anyway, thanks for your help and answers.

I think that is a good decision. The whole layout of your app may change later, and you may discover that what is a visual issue now is no issue later. And when you have a full working app as a showcase, then motivation for GTK core devs may be greater to spent time helping you. Because it is not much fun spending time trying to help people, when that people vanish a few weeks later and never return.

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.