Message: stackrpms customizations to fbxkb Author: bgstack15 Date: 2022-10-10 Version: 0.6 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3a9bccc --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.*.swp +*.o +config.h +man/*.gz +*.dep +fbxkb +fbxkb.c.* +Makefile.config diff --git a/fbxkb.c b/fbxkb.c index 2341464..fb5f665 100644 --- a/fbxkb.c +++ b/fbxkb.c @@ -170,7 +170,7 @@ app_menu_about(GtkWidget *widget, gpointer data) GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, - "fbxkb %s\nX11 Keyboard switcher\nAuthor: Anatoly Asviyan ", version); + "fbxkb %s\nX11 Keyboard switcher\nOriginal author: Anatoly Asviyan \ncustomized for stackrpms by bgstack15", version); /* Destroy the dialog when the user responds to it (e.g. clicks a button) */ g_signal_connect_swapped (about_dialog, "response", G_CALLBACK (gtk_widget_hide), @@ -205,6 +205,12 @@ static void docklet_destroyed(GtkWidget *widget, void *data) RET(); } +int scroll_input_method(int no) { + no = (cur_group + no) % ngroups; + DBG("no=%d\n", no); + XkbLockGroup(dpy, XkbUseCoreKbd, no); + return no; +} void docklet_clicked(GtkWidget *button, GdkEventButton *event, void *data) { @@ -213,13 +219,9 @@ void docklet_clicked(GtkWidget *button, GdkEventButton *event, void *data) if (event->type != GDK_BUTTON_PRESS) RET(); - if (event->button == 1) { - int no; - - no = (cur_group + 1) % ngroups; - DBG("no=%d\n", no); - XkbLockGroup(dpy, XkbUseCoreKbd, no); - } else if (event->button == 2) { + if (event->button == 2) { + scroll_input_method(1); + } else if (event->button == 1) { gtk_menu_popup(GTK_MENU(flag_menu), NULL, NULL, NULL, NULL, event->button, event->time); } else if (event->button == 3) { gtk_menu_popup(GTK_MENU(app_menu), NULL, NULL, NULL, NULL, event->button, event->time); @@ -227,6 +229,26 @@ void docklet_clicked(GtkWidget *button, GdkEventButton *event, void *data) RET(); } +void docklet_scrolled(GtkWidget *button, GdkEventScroll *event, void *data) { + char *i = NULL; + int no = 0; + switch (event->direction) { + case GDK_SCROLL_UP: + case GDK_SCROLL_LEFT: + i = "up"; + no = -1; + break; + case GDK_SCROLL_DOWN: + case GDK_SCROLL_RIGHT: + i = "down"; + no = 1; + break; + } + if (i) { + scroll_input_method(no); + } +} + static int docklet_create() { @@ -240,6 +262,7 @@ docklet_create() g_signal_connect(G_OBJECT(docklet), "embedded", G_CALLBACK(docklet_embedded), NULL); g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_destroyed), NULL); g_signal_connect(G_OBJECT(box), "button-press-event", G_CALLBACK(docklet_clicked), NULL); + g_signal_connect(G_OBJECT(docklet), "scroll-event", G_CALLBACK(docklet_scrolled), NULL); gtk_container_set_border_width(GTK_CONTAINER(box), 0); @@ -257,7 +280,7 @@ docklet_create() static gboolean my_str_equal (gchar *a, gchar *b) { - return (a[0] == b[0] && a[1] == b[1]); + return strcmp(a,b) == 0; } @@ -273,10 +296,12 @@ sym2flag(char *sym) if (flag) RET(flag); - if (!s) - s = g_string_new(IMGPREFIX "tt.png"); - s->str[s->len-6] = sym[0]; - s->str[s->len-5] = sym[1]; + if (!s) + s = g_string_new(IMGPREFIX); + else + s = g_string_assign(s,IMGPREFIX); + s = g_string_append(s, sym); + s = g_string_append(s, ".png"); flag = gdk_pixbuf_new_from_file_at_size(s->str, 24, 24, NULL); if (!flag) RET(zzflag); @@ -341,7 +366,7 @@ read_kbd_description() // parse kbd info if (sym_name_atom != None) { - char *sym_name, *tmp, *tok; + char *sym_name, *tmp, *tok, *tmp2, *tmp3; int no; sym_name = XGetAtomName(dpy, sym_name_atom); @@ -352,6 +377,7 @@ read_kbd_description() * 150 pc/pc(pc101)+pc/us+pc/ru(phonetic):2+group(shift_toggle) * 470 pc(pc105)+us+ru(phonetic):2+il(phonetic):3+group(shifts_toggle)+group(switch) */ + tmp3 = malloc(30 * sizeof(char)); DBG("sym_name=%s\n", sym_name); for (tok = strtok(sym_name, "+"); tok; tok = strtok(NULL, "+")) { DBG("tok=%s\n", tok); @@ -364,6 +390,13 @@ read_kbd_description() } else { no = 0; } + if((tmp2 = strchr(tok, '('))) { + // these next two statements could be done cleverly in one statement but the compiler warns if you try it. + // strip left paren, and then right paren + tmp2++; + tmp2[strlen(tmp2)-1] = '\0'; + } + DBG("tmp2=%s\n", tmp2); for (tmp = tok; isalpha(*tmp); tmp++); *tmp = 0; @@ -375,9 +408,18 @@ read_kbd_description() if (group2info[no].sym != NULL) { ERR("xkb group #%d is already defined\n", no); } - group2info[no].sym = g_strdup(tok); - group2info[no].flag = sym2flag(tok); + strcpy(tmp3, tok); + if (tmp2 != 0) { + strcat(tmp3,","); + // add variant to end of string for the png lookup + strcat(tmp3,tmp2); + *tmp2 = 0; + } + DBG("tmp3=%s\n",tmp3); + group2info[no].sym = g_strdup(tmp3); + group2info[no].flag = sym2flag(tmp3); group2info[no].name = XGetAtomName(dpy, kbd_desc_ptr->names->groups[no]); + *tmp3 = 0; } XFree(sym_name); } @@ -412,6 +454,7 @@ static void update_flag(int no) g_assert(k != NULL); DBG("k->sym=%s\n", k->sym); gtk_image_set_from_pixbuf(GTK_IMAGE(image), k->flag); + gtk_widget_set_tooltip_text(docklet, k->name); RET(); } @@ -430,8 +473,9 @@ filter( XEvent *xev, GdkEvent *event, gpointer data) if (xkbev->any.xkb_type == XkbStateNotify) { DBG("XkbStateNotify: %d\n", xkbev->state.group); cur_group = xkbev->state.group; - if (cur_group < ngroups) + if (cur_group < ngroups) { update_flag(cur_group); + } } else if (xkbev->any.xkb_type == XkbNewKeyboardNotify) { DBG("XkbNewKeyboardNotify\n"); read_kbd_description(); diff --git a/images/us,basic.png b/images/us,basic.png new file mode 120000 index 0000000..ea19c57 --- /dev/null +++ b/images/us,basic.png @@ -0,0 +1 @@ +us.png \ No newline at end of file