20 votes

Comment ajouter une applet d'état de modification du clavier au panneau Unity ?

Je suis un utilisateur de KDE qui envisage de passer à Unity. En raison d'un handicap manuel, j'utilise Clés collantes et dans KDE, j'ai une applet dans le panneau système qui montre quelles touches modificatrices sont actives. Je me souviens que Gnome avait aussi cette fonctionnalité, tout comme Windows et OS X.

Comment ajouter l'applet d'état des modificateurs de clavier au panneau dans Unity ?

Clarification : J'ai déjà activé les touches adhésives. Je demande comment ajouter un applet qui indique l'état des touches de modification . Cet indicateur indiquerait quand la touche Shift est enfoncée, quand la touche Alt est enfoncée, quand la touche Tux est enfoncée et quand la touche Ctrl est enfoncée. Cette applet existe dans tous les principaux environnements de bureau (KDE, Windows, Mac OSX et Gnome). Elle est nécessaire pour l'accessibilité du bureau.

Voici une image de l'applet d'état des modificateurs de clavier, à côté de l'applet d'indicateur de disposition du clavier. Les modificateurs représentés sont, de gauche à droite, Shift , Ctrl , Alt , I-dont-know-this-one , Tux/Win , NumLock y CapsLock . On peut voir que la touche NumLock est active.

enter image description here

8voto

user.dz Points 45060

Il s'agit d'une question en suspens dans Unity :

Le code ci-dessous a été mis à jour, maintenant il peut utiliser des icônes pour montrer l'état. Mais il peut être lent de temps en temps car je dois mettre à jour le fichier d'icônes sur le disque dur puis le recharger à nouveau. (Voir les notes à propos de ce problème/limitation dans libappindicator )

Une version bien packagée a été mise à disposition sur le ppa webupd8 (Merci à Alin Andrei /Andrew/).

sudo add-apt-repository ppa:nilarimogard/webupd8
sudo apt-get update
sudo apt-get install indicator-xkbmod

Référence : Indicateur d'état des modificateurs de clavier pour Ubuntu : Indicateur Xkbmod


Réponse originale :

Il ne s'agit pas d'une réponse canonique à la question. Elle pourrait être considérée comme une solution de contournement. En espérant que quelqu'un écrive une solution sophistiquée pour cela.

Il s'agit d'un prototype simple d'indicateur de modification du clavier pour Unity.

Image à partir de la gauche : Icône, Shift, Caps verrouillées, Ctrl, Alt, Super, AltGr verrouillées (Petit cercle pour indiquer l'état verrouillé)

screenshot of unity-xkbmod prototype

Fichier source unity-xkbmod.c :

/*
 * unity-xkbmod.c
 *
 * Copyright 2014 Sneetsher <sneetsher@localhost>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 *
 *
 */

#include <string.h>

#include <X11/XKBlib.h>

#include <glib/gprintf.h>
#include <gtk/gtk.h>
#include <libappindicator/app-indicator.h>

//callback data structure
typedef struct _AppData {
  Display *_display;
  int *_deviceId;
  AppIndicator *indicator;
} AppData;

//menu ui
static GtkActionEntry entries[] = {
  { "Quit",     "application-exit", "_Quit", "<control>Q",
    "Exit the application", G_CALLBACK (gtk_main_quit) },
};

static guint n_entries = G_N_ELEMENTS (entries);

static const gchar *ui_info =
"<ui>"
"  <popup name='IndicatorPopup'>"
"    <menuitem action='Quit' />"
"  </popup>"
"</ui>";

//callback function, get xkb state, update indicator label (icon have limitation)
static gboolean update_xkb_state (gpointer data)
{
  //get xkb state
  XkbStateRec xkbState;
  XkbGetState(((AppData*) data)->_display, *(((AppData*) data)->_deviceId), &xkbState);

  //construct label
  GString *label = g_string_new("");

  register int i;
  unsigned bit;

  //loop taken from xkbwatch source
  for (i = XkbNumModifiers - 1, bit = 0x80; i >= 0; i--, bit >>= 1)
  {
    //printf("base%d %s  ", i, (xkbState.base_mods & bit) ? "on " : "off");
    //printf("latched%d %s  ", i, (xkbState.latched_mods & bit) ? "on " : "off");
    //printf("locked%d %s  ", i, (xkbState.locked_mods & bit) ? "on " : "off");
    //printf("effective%d %s  ", i, (xkbState.mods & bit) ? "on " : "off");
    //printf("compat%d %s\n", i, (xkbState.compat_state & bit) ? "on " : "off");

    //todo: change constant with xkb modifier constant (defined in the headers)
    // show effective modifier stat
    switch (i)
    {
      case 7:
        g_string_prepend (label,  ((xkbState.mods & bit) ? "" : ""));
        break;
      case 6:
        g_string_prepend (label,  ((xkbState.mods & bit) ? "" : ""));
        break;
      case 5:
        g_string_prepend (label,  ((xkbState.mods & bit) ? "5" : ""));
        break;
      case 4:
        g_string_prepend (label,  ((xkbState.mods & bit) ? "" : ""));
        break;
      case 3:
        g_string_prepend (label,  ((xkbState.mods & bit) ? "" : ""));
        break;
      case 2:
        g_string_prepend (label,  ((xkbState.mods & bit) ? "" : ""));
        break;
      case 1:
        g_string_prepend (label,  ((xkbState.mods & bit) ? "" : ""));
        break;
      case 0:
        g_string_prepend (label,  ((xkbState.mods & bit) ? "" : ""));
        break;
      default:
        break;
    };

    // show if modifier is locked
    g_string_prepend (label,  ((xkbState.locked_mods & bit) ? " " : " "));
  }

  //g_string_prepend (label,  "");
  app_indicator_set_label (((AppData*) data)->indicator, label->str, NULL);

  //g_free(label);
  return TRUE;
}

int main (int argc, char **argv)
{
  AppData appdata;
  Display *_display;
  int _deviceId;

  char* displayName = strdup("");
  int eventCode;
  int errorReturn;
  int major = XkbMajorVersion;
  int minor = XkbMinorVersion;;
  int reasonReturn;

  AppIndicator *indicator;
  GtkWidget *indicator_menu;
  GtkUIManager *uim;
  GtkActionGroup *action_group;
  GError *error = NULL;

  gtk_init (&argc, &argv);

  XkbIgnoreExtension(False);

  g_printf("Xkb client lib ver: %d.%d\n" , major , minor );
  _display = XkbOpenDisplay(displayName, &eventCode, &errorReturn,
                            &major, &minor, &reasonReturn);
  g_printf("Xkb server lib ver: %d.%d\n" , major , minor );

  if (reasonReturn != XkbOD_Success)
  {
    g_printf("Unable to open display!\n");
    return 1;
  }

  XkbDescRec* kbdDescPtr = XkbAllocKeyboard();
  if (kbdDescPtr == NULL)
  {
    g_printf ("Failed to get keyboard description.\n");
    return 2;
  }
  kbdDescPtr->dpy = _display;
  _deviceId = kbdDescPtr->device_spec;

  /*
  //no need for event listener, used gtk_timeout timer
  XkbSelectEventDetails(_display, XkbUseCoreKbd, XkbStateNotify,
                     XkbAllStateComponentsMask, XkbGroupStateMask);
  */

  action_group = gtk_action_group_new ("AppActions");
  gtk_action_group_add_actions (action_group, entries, n_entries, NULL);

  indicator = app_indicator_new_with_path (
                                        "Simple XKB Modifier Indicator",
                                        "icon",
                                        APP_INDICATOR_CATEGORY_HARDWARE,
                                        g_get_current_dir());

  uim = gtk_ui_manager_new ();
  gtk_ui_manager_insert_action_group (uim, action_group, 0);
  if (!gtk_ui_manager_add_ui_from_string (uim, ui_info, -1, &error))
  {
    g_printf ("Failed to build menus: %s\n", error->message);
    g_error_free (error);
    error = NULL;
    return 3;
  }

  indicator_menu = gtk_ui_manager_get_widget (uim, "/ui/IndicatorPopup");
  app_indicator_set_menu (indicator, GTK_MENU (indicator_menu));
  app_indicator_set_status (indicator, APP_INDICATOR_STATUS_ACTIVE);

  //app_indicator_set_label (indicator, "       ", NULL);
  //symbols: shift U21E7 ctrl U22C0 alt/altgr U2325 U2387  cmd U2318
  //from font: DejaVu Sans

  appdata._display = _display;
  appdata._deviceId = &_deviceId;
  appdata.indicator = indicator;
  gtk_timeout_add (120, (GtkFunction) update_xkb_state, &appdata);
  //nice for realtime tasks, to replace gtk_timeout
  //gtk_idle_add ((GtkFunction) idle_func, &appdata);

  gtk_main ();

  XCloseDisplay (_display);
  return 0;
}
  1. Installation des en-têtes/libs nécessaires : (Je ne suis pas sûr d'en avoir oublié)

    sudo apt-get install libx11-dev libappindicator-dev libgtk2.0-dev
  2. Compilation :

    pré> gcc -Wall unity-xkbmod.c -o unity-xkbmod `pkg-config --cflags --libs appindicator-0.1` -lX11

  3. Cours :

    ./unity-xkbmod

Nota:

  • libappindicator utilisés pour les indicateurs Unity manquent d'une caractéristique importante qui facilite l'utilisation d'autres indicateurs de bureau. Voir le bogue n° 812067 API nécessaire : support du réglage des icônes pixbuf

    Sans cette fonctionnalité, disons que nous avons besoin de (Shift, Ctrl, Alt, AltGr, Super) avec des touches adhésives actives ; nous avons 3 statuts principaux pour chacun (Off, On/Latched, Locked). Donc 3^5 des icônes combinées devraient être générées. (Dans le cas normal, il suffit de 3x5 icônes uniques)

    C'est pourquoi j'ai utilisé l'étiquette de l'indicateur avec des symboles de DejaVu Sans police.

  • Pour mettre une icône, placez-la dans le même dossier et nommez-la comme suit icon.* . Formats acceptés : png, svg, ico, xpm ...

    Si vous n'aimez pas une icône, créez simplement une image de 1x1 px à la place.

Références :

2voto

user.dz Points 45060

Une autre solution qui n'est pas parfaite, mais que certains peuvent trouver utile car il est possible d'avoir une fonctionnalité complète comme dans KDE comme l'activation d'un mod avec un clic.

  1. installer kbstate applet

    sudo apt-get install plasma-widget-kbstate kde-workspace-bin
  2. Exécutez-le dans plasma-windowed joueur

    • Fenêtre ordinaire

      plasma-windowed kbstate

      screenshot of plasma-widget-kbstate in Xubuntu

    • Fenêtre sans bordure

      plasma-windowed --noborder kbstate

      screenshot of borderless plasma-widget-kbstate in Unity

Je n'ai pas eu beaucoup de temps pour jouer avec, mais wmctrl peut aider à positionner, redimensionner et faire en sorte qu'il soit au top au lancement.

Référence : Quelle commande pour lancer un plasmoïde kde et le menu kickstart ?

1voto

Elder Geek Points 34144

J'ai fait une recherche pour Ubuntu sticky keys monitor et j'ai trouvé quelque chose qui pourrait être utile ici : http://code.google.com/p/key-mon/

show case screenshot

Essayez de courir

key-mon --sticky pour le support des touches adhésives.

Référence : http://code.google.com/p/key-mon/

Notez que la version disponible via le centre logiciel est 1.6-0ubuntu1. Publiée en juin 2011, elle ne prend pas en charge le commutateur --sticky. Si l'indicateur ressemble exactement à celui ci-dessus, vous avez l'ancienne version. Essayez la dernière version à l'adresse suivante http://code.google.com/p/key-mon/ Au moment où nous écrivons ces lignes, il s'agit de keymon_1.17-1_all.deb 229 KB Diffusé le 3 janvier 2014. Le support de l'interrupteur --sticky a été testé et confirmé.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X