[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

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.

2 Likes

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