Unity paneline klavye değiştirici durumu uygulaması nasıl eklenir?


18

Ben Birliğe geçmeyi düşünen bir KDE kullanıcısıyım. Manuel sakatlık nedeniyle, yapışkan tuşları kullanıyorum ve KDE'de sistem panelinde hangi değiştirici tuşların etkin olduğunu gösteren bir uygulama var. Gnome'un da bu özelliğe sahip olduğunu hatırlıyorum, Windows ve OS X de öyle.

Klavye değiştirici durum uygulaması Unity'deki panele nasıl uygulanır?

Açıklama: Yapışkan tuşları zaten etkinleştirdim. Değiştirici tuşların durumunu gösteren bir uygulama nasıl ekleyeceğinizi soruyorum . Bu gösterge, Shift tuşuna basıldığında, Alt tuşuna basıldığında, Tux tuşuna basıldığında ve Ctrl tuşuna basıldığında gösterilir. Bu uygulama tüm büyük masaüstü ortamlarında (KDE, Windows, Mac OSX ve Gnome) bulunur. Masaüstünün erişilebilirliği için gereklidir.

Klavye düzen göstergesi uygulamasının yanında, klavye değiştirici durum uygulamasının bir görüntüsü. Temsil düzenleyiciler, soldan oldukları anda, Shift, Ctrl, Alt, I-dont-know-this-one, Tux/Win, NumLock, ve CapsLock. NumLock tuşunun etkin olduğu görülebilir.

resim açıklamasını buraya girin


Hata ... Bu konuda büyük bir boşluk var gibi görünüyor ... Bir değiştirici tuşa basıldığında bip sesi olacak bir şey var.
Wilf

@wilf Yanılmıyorsam, Unity'de bir Erişilebilirlik simgesi (Gnome 3 ile aynı) vardır ancak kullanıcıyı durum hakkında bilgilendirmek için "ekstra" simgesi yoktur.
Braiam

4
@Takkat: Öneri için teşekkürler. indicator-keylockSadece geleneksel klavyenin üzerinde devlet göstergelerini sahip olan anahtarların durumunu görüntüler: CapsLock, ScrollLock, NumLock. I standardı değiştirici tuşları durumunu gösteren bir gösterge gerekir: Shift, Ctrl, Tux, Alt. Tüm büyük masaüstü bilgisayarlarda (KDE, Windows, Mac OSX) bu gösterge uygulaması vardır.
dotancohen

1
KDE aracının paket adının da bahsettiğinize inanıyorum ve plasma-widget-kbstateyazılım merkezinde hızlı bir arama gerçekten de eşdeğer sonuçlara uymuyor
Daniel W.

2
@ shengy: KB State plazmoid kullanıyorum. Kubuntu kullanıyorsanız, yükleyin sudo apt-get install plasma-widget-kbstate.
dotancohen

Yanıtlar:


7

Bu Unity'de göze çarpan bir konudur:

Aşağıdaki kod güncellendi, şimdi durumu göstermek için simgeler kullanabilir. Ancak sabit sürücüdeki simge dosyasını güncellemem ve tekrar yüklemem gerektiğinden bazen yavaşlayabilir. (Bu sorunla ilgili notlara / içindeki sınırlamaya bakın libappindicator)

Webupd8 ppa'da iyi paketlenmiş bir sürüm sağlandı (Teşekkürler Alin Andrei / Andrew / 'e gider)

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

Referans: Klavye Değiştiricileri Durum göstergesi Ubuntu için: Xkbmod Göstergesi


Orijinal Yanıt:

Bu soruya kanonik bir cevap olarak katılmaz. Etrafında bir çalışma olarak sayılabilir. Birisinin umuduyla bunun için sofistike bir çözüm yazar.

Bu Unity için basit bir prototip klavye değiştiricileri göstergesi.

Soldan başlayan görüntü: Simge, Shift, Kilitli Büyük Harfler, Ctrl, Alt, Süper, Kilitli AltGr (Kilitli durumu gösteren küçük daire)

unity-xkbmod prototype ekran görüntüsü

Kaynak dosya 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. Gerekli üstbilgileri / kütüphaneleri yükleme: (Herhangi birini özlediğimden emin değilim)

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

    gcc -Wall unity-xkbmod.c -o unity-xkbmod `pkg-config --cflags --libs appindicator-0.1` -lX11
    
  3. Çalıştırmak:

    ./unity-xkbmod
    

Not:

  • libappindicatorUnity göstergeleri için kullanılan diğer masaüstü göstergelerinin bağlantı noktalarını kolaylaştıran önemli bir özellik yoktur. Bkz. Hata # 812067 API gerekli: pixbuf simge ayarı desteği

    Bu özellik olmadan, yapışkan tuşlar etkinken (Shift, Ctrl, Alt, AltGr, Super) ihtiyacımız olduğunu varsayalım; her biri için 3 ana durumumuz var (Kapalı, Açık / Mandallı, Kilitli). Bu yüzden 3 ^ 5 kombine ikonlar oluşturulmalıdır. (Normal durumda sadece 3x5 tek simgeler)

    Bu yüzden DejaVu Sans yazı tipinden sembollerle gösterge etiketi kullandım .

  • Bir simge koymak için, aynı klasöre yerleştirin ve adlandırın icon.*. Kabul edilen biçimler: png, svg, ico, xpm ...

    Herhangi bir simgeyi beğenmediyseniz bunun yerine 1x1 piksel boyutunda bir resim oluşturun.

Referanslar:


Güzel, teşekkürler! Bunu deneyeceğim ve size geri döneceğim. İyi iş çıkardın, Sneetsher!
dotancohen

Diz çöktüğünü!
dotancohen

evet, teşekkür ederim @dotancohen. En azından Unity'yi kullanabilirsiniz, sabit konum simgeleri olmadan çirkin olabilir mi?
user.dz

1
Çirkin değil, benim resmimi görmelisin! Bu sorundan Ubuntu hata izleme aracında bahsetmiştim .
dotancohen

1
Sneetsher, tekrar teşekkür etmek istedim. Şimdi Unity'ye taşındım ve bu müthiş uygulama olmadan hamle imkansız olurdu. Ayrıca koddan biraz öğrendim. Teşekkür ederim!
dotancohen

2

Mükemmel olmayan başka bir çözüm, ancak bazıları KDE'de olduğu gibi tam bir modele sahip olmanın mümkün olduğu için yararlı olabilir.

  1. kbstateuygulamayı yükle

    sudo apt-get install plasma-widget-kbstate kde-workspace-bin
    
  2. plasma-windowedOynatıcıda çalıştır

    • Normal pencere

      plasma-windowed kbstate
      

      plasma-widget-kbstate in Xubuntu ekran görüntüsü

    • Kenarlıksız pencere

      plasma-windowed --noborder kbstate
      

      Unity içinde kenarlıksız plazma-widget-kbstate ekran görüntüsü

Oynamak için çok zamanım yoktu, ama wmctrl lansman sırasında konumlandırmaya, yeniden boyutlandırmaya ve zirveye çıkarmaya yardımcı olabilir.

Referans: Bir kde plazmoid ve kickstart menüsünü başlatmak için hangi komut


1

Ubuntu yapışkan tuşları monitörü için bir arama yaptım ve burada yardımcı olabilecek bir şey buldum: http://code.google.com/p/key-mon/

vaka ekran görüntüsünü göster

Koşmayı dene

key-mon --sticky Yapışkan tuş desteği.

Referans: http://code.google.com/p/key-mon/

Yazılım merkezi aracılığıyla sunulan sürümün 1.6-0ubuntu1 olduğunu unutmayın. --Sticky switch'i desteklemeyen Haziran 2011'de çıktı. Gösterge tam olarak yukarıdakine benziyorsa daha eski bir sürüme sahipsiniz Bu yazıdan itibaren http://code.google.com/p/key-mon/ adresinden en son sürümü deneyin. Keymon_1.17-1_all.deb 229 KB Çıkış 3 Ocak 2014. - yapışkan anahtar desteği test edildi ve onaylandı.


1
Nice find, ancak değiştirici tuşların durumunu değil key-mon, hangi düğmeye basıldığını gösterir . Ayrım olmasıdır un preslenmiş durum geri döner düğme sonra 1 saniye preslenmiştir . Bir klavye değiştirici durum uygulaması , bir sonraki tuşa basış gerçekleştiğinde ekranı basılmamış duruma döndürür ve bu nedenle 'basılı' durumunu devre dışı bırakır . key-mon
dotancohen

yeniden düzenlenmiş cevap.
Elder Geek

Karışıklık için özür dilerim. Tam olarak ihtiyacınız olanı sağlamak için cevabı (tekrar) düzenledim.
Elder Geek

1
Teşekkürler Elder Geek. --stickyOpsiyon devlet diğer anahtarlar izlerken, yerine düzgün klavye değiştirici devlet uygulamaları gibi düzgün bir arayüz sorgulayarak değiştirici tuşlarının durumunu tahmin eden yok galiba. Bu, bir değiştirici tuşa iki kez basılarak görülebilir: ilk kez uygulamadaki göstergeyi etkinleştirir, ancak ikinci kez bırakmaz. Dolayısıyla, devletin yanlış olmadığı zaman aktif olduğu bildirilir. Bu hata , sorunu kısmen ele alıyor, orada ve ek hatalarda ayrıntıları dolduracağım. Teşekkür ederim.
dotancohen

1
@dotancohen "Bir klavye değiştirici durum uygulamasının, bir sonraki tuşa basma gerçekleştiğinde ekranı basılmamış duruma döndüreceğini ve bu nedenle" basılı "durumunu devre dışı bırakacağını belirten ifadenize dayanarak test ettim. ve kimse değiştirici anahtara arka arkaya iki kez vurmak beni hiç şaşırtmadı. Gözetim için özür dilerim.
Elder Geek
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.