[help] Remove outline keyboard focus in gtk3 / Gtk Entry

I have been working on a simple form with GTK3 but when I put a text input I have a bug that shows a border in all the widgets, how could I solve it?

it’s really awkward to have that border on all elements and it only happens when I put text in entry

Attached image

Maybe not the best headline, sorry for my English, I’m Spanish

output

#include <gtk/gtk.h>

// Estos son los widgets que usaremos en el programa
GtkWidget *user, *pass, *confirm, *clear, *check;
// Una expresión regular para los GtkEntry
GRegex *patt;

// Crea un GtkGrid con los widgets a usar y lo retorna
GtkWidget* build_grid() {
  GtkWidget *label;

  // El GtkGrid a retornar
  GtkWidget *grid = g_object_new(
    GTK_TYPE_GRID,
    "visible", TRUE,
    "column-spacing", 6,
    "row-spacing", 6,
    "halign", GTK_ALIGN_CENTER,
    "valign", GTK_ALIGN_CENTER,
    NULL
  );

  user    = g_object_new(GTK_TYPE_ENTRY, "visible", TRUE, NULL);

  pass    = g_object_new(
    GTK_TYPE_ENTRY,
    "visible", TRUE,
    "visibility", FALSE,
    "input-purpose", GTK_INPUT_PURPOSE_PASSWORD,
    NULL
  );

  confirm = g_object_new(
    GTK_TYPE_ENTRY,
    "visible", TRUE,
    "visibility", FALSE,
    "input-purpose", GTK_INPUT_PURPOSE_PASSWORD,
    NULL
  );

  label = g_object_new(
    GTK_TYPE_LABEL,
    "label", "Usuario",
    "visible", TRUE,
    "xalign", 1.0,
    NULL
  );

  gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1);
  gtk_grid_attach(GTK_GRID(grid), user, 1, 0, 1, 1);

  label = g_object_new(
    GTK_TYPE_LABEL,
    "label", "Contraseña",
    "visible", TRUE,
    "xalign", 1.0,
    NULL
  );

  gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1);
  gtk_grid_attach(GTK_GRID(grid), pass, 1, 1, 1, 1);

  label = g_object_new(
    GTK_TYPE_LABEL,
    "label", "Repita la contraseña",
    "visible", TRUE,
    "xalign", 1.0,
    NULL
  );

  gtk_grid_attach(GTK_GRID(grid), label, 0, 2, 1, 1);
  gtk_grid_attach(GTK_GRID(grid), confirm, 1, 2, 1, 1);

  check = g_object_new(
    GTK_TYPE_CHECK_BUTTON,
    "label", "Mostrar contraseña",
    "visible", TRUE,
    NULL
  );

  clear = g_object_new(
    GTK_TYPE_BUTTON,
    "label", "Limpiar",
    "visible", TRUE,
    "halign", GTK_ALIGN_END,
    NULL
  );

  gtk_grid_attach(GTK_GRID(grid), check, 1, 3, 1, 1);
  gtk_grid_attach(GTK_GRID(grid), clear, 1, 4, 1, 1);

  return grid;
}

gboolean user_input(GtkWidget *self, GdkEvent *ev, gpointer data) {
  const char *val = gtk_entry_get_text(GTK_ENTRY(self));

  if ( g_regex_match(patt, val, 0, NULL) ) {
    gtk_entry_set_icon_from_icon_name(
      GTK_ENTRY(self),
      GTK_ENTRY_ICON_SECONDARY, "process-completed-symbolic"
    );
  } else {
    gtk_entry_set_icon_from_icon_name(
      GTK_ENTRY(self),
      GTK_ENTRY_ICON_SECONDARY, "process-error-symbolic"
    );
  }

  return FALSE;
}

gboolean confirm_input(GtkWidget *self, GdkEvent *ev, gpointer data) {
  const char *original     = gtk_entry_get_text(GTK_ENTRY(pass));
  const char *confirmation = gtk_entry_get_text(GTK_ENTRY(self));

  if ( g_str_equal(confirmation, original) ) {
    gtk_entry_set_icon_from_icon_name(
      GTK_ENTRY(self),
      GTK_ENTRY_ICON_SECONDARY, "process-completed-symbolic"
    );
  } else {
    gtk_entry_set_icon_from_icon_name(
      GTK_ENTRY(self),
      GTK_ENTRY_ICON_SECONDARY, "process-error-symbolic"
    );
  }

  return FALSE;
}

void check_toggled(GtkWidget *self, gpointer data) {
  gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(self));

  if (active) {
    gtk_entry_set_visibility(GTK_ENTRY(pass),    TRUE);
    gtk_entry_set_visibility(GTK_ENTRY(confirm), TRUE);
  } else {
    gtk_entry_set_visibility(GTK_ENTRY(pass),    FALSE);
    gtk_entry_set_visibility(GTK_ENTRY(confirm), FALSE);
  }
}

void clear_clicked(GtkWidget *self, gpointer data) {
  gtk_entry_set_text(GTK_ENTRY(user),    "");
  gtk_entry_set_text(GTK_ENTRY(pass),    "");
  gtk_entry_set_text(GTK_ENTRY(confirm), "");
}

void app_activate(GtkApplication *self, gpointer data) {
  GtkWidget *win = g_object_new(
    GTK_TYPE_APPLICATION_WINDOW,
    "application", self,
    "border-width", 10,
    NULL
  );

  gtk_container_add(GTK_CONTAINER(win), build_grid());

  patt = g_regex_new("^([a-z]+[a-z0-9]*)$", 0, 0, NULL);

  g_signal_connect(user,    "notify::text", G_CALLBACK(user_input),    NULL);
  g_signal_connect(confirm, "notify::text", G_CALLBACK(confirm_input), NULL);
  g_signal_connect(check,   "toggled",      G_CALLBACK(check_toggled), NULL);
  g_signal_connect(clear,   "clicked",      G_CALLBACK(clear_clicked), NULL);

  gtk_window_present(GTK_WINDOW(win));
}

int main(int argc, char **argv) {
  GtkApplication *app = gtk_application_new("org.example.gtk.password", G_APPLICATION_FLAGS_NONE);
  g_signal_connect(app, "activate", G_CALLBACK(app_activate), NULL);

  int res = g_application_run(G_APPLICATION(app), argc, argv);
  g_object_unref(app);
  g_clear_pointer(&patt, g_regex_unref);

  return res;
}

That’s the keyboard focus outline, it’s not a bug - it’s a feature!

Remember you can use space/enter to “activate” things like tick boxes

2 Likes

And how do I deactivate it?
I don’t want keyboard focus outline :confused:

Create ~/.config/gtk-3.0/gtk.css and include this line:

* { outline-width: 0px; }

or this line:

* { outline: none; }

That should do it. You may need to switch away from the current gtk3 theme to another and back for the change to take effect. On some systems, a log out and log in maybe needed.

or create a css in my new application

output

1 Like

I mean sure that “works” - assuming you don’t care about a11y/keynav

You probably want to keep this CSS specific to only your application. Adding it globally can break the understanding of users who use your app and also other apps.
https://developer.gnome.org/gtk3/stable/chap-css-overview.html

2 Likes

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