Unityパネルにキーボード修飾子状態アプレットを追加する方法は?


18

私はUnityへの移行を考えているKDEユーザーです。手動での障害のため、スティッキーキーを使用します。KDEでは、システムパネルにアプレットがあり、どの修飾キーがアクティブになっているかがわかります。Gnomeにもこの機能があったことを思い出します。WindowsとOS Xも同様です。

キーボード修飾子状態の広告は、Unityのパネルにどのように表示されますか?

明確化:スティッキーキーを既に有効にしました。修飾キーの状態示すアプレットを追加する方法を尋ねています。このインジケータは、Shiftキーが押されたとき、Altキーが押されたとき、Tuxキーが押されたとき、Ctrlキーが押されたときに表示されます。このアプレットは、すべての主要なデスクトップ環境(KDE、Windows、Mac OSX、およびGnome)に存在します。デスクトップのアクセシビリティのために必要です。

これは、キーボードレイアウトインジケータアプレットの横にある、キーボードモディファイヤステートアプレットの画像です。代表修飾子は、左から右へ、です、ShiftCtrlAltI-dont-know-this-oneTux/WinNumLock、とCapsLock。NumLockキーがアクティブになっていることがわかります。

ここに画像の説明を入力してください


エラー...これに関しては大きなギャップがあるようです...しかし、修飾キーが押されたときにビープ音を鳴らすことがあります。
ウィルフ14年

@wilf Unityにアクセシビリティアイコン(Gnome 3と同じ)はありますが、ユーザーにステータスを通知するための「追加」アイコンはありません。
ブライアン14年

4
@Takkat:ご提案ありがとうございます。indicator-keylock唯一の伝統的なキーボード自体に状態の指標を持っているこれらのキーの状態が表示されますCapsLockScrollLockNumLock。私は、標準的な修飾キーの状態を示している指標が必要になりますShiftCtrlTuxAlt。すべての主要なデスクトップ(KDE、Windows、Mac OSX)には、このインジケーターアプレットがあります。
dotancohen

1
私はあなたがあまりにも言及しているKDEツールのパケット名があると信じてplasma-widget-kbstate、ソフトウェアの中心にあるクイック検索は、実際には任意の同等の結果に耳を傾けていません
ダニエル・W.

2
@shengy:KB State plasmoidを使用しています。Kubuntuを使用している場合は、でインストールしsudo apt-get install plasma-widget-kbstateます。
-dotancohen

回答:


7

これはUnityの未解決の問題です。

以下のコードが更新され、アイコンを使用して状態を表示できるようになりました。ただし、ハードドライブのアイコンファイルを更新してから再度読み込む必要があるため、時間がかかる場合があります。(この問題/制限に関する注意事項を参照してくださいlibappindicator

よくパッケージ化されたリリースがwebupd8 ppaで利用可能になりました(Alin Andrei / Andrew /に感謝します)

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

参照:キーボード修飾子の状態インジケーターUbuntuの場合:Xkbmodインジケーター


元の回答:

これは、質問に対する標準的な回答として出席されていません。回避策として数えることができます。誰かがそのための洗練されたソリューションを書くことを望んでいます。

これは、Unity用の単純なプロトタイプキーボード修飾子インジケーターです。

左から始まる画像:アイコン、Shift、ロックされたCaps、Ctrl、Alt、Super、ロックされたAltGr(ロック状態を示す小さな円)

unity-xkbmodプロトタイプのスクリーンショット

ソースファイル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. 必要なヘッダー/ライブラリのインストール:(見逃したかどうかわからない)

    sudo apt-get install libx11-dev libappindicator-dev libgtk2.0-dev
    
  2. コンパイル:

    gcc -Wall unity-xkbmod.c -o unity-xkbmod `pkg-config --cflags --libs appindicator-0.1` -lX11
    
  3. 実行:

    ./unity-xkbmod
    

注意:

  • libappindicatorUnityインジケーターに使用される他のデスクトップインジケーターを簡単に移植できる重要な機能がありません。Bug#812067必要なAPIを参照してください:pixbufアイコン設定のサポート

    この機能がない場合、スティッキーキーをアクティブにして(Shift、Ctrl、Alt、AltGr、Super)が必要だとしましょう。それぞれに3つの主要なステータス(オフ、オン/ラッチ、ロック)があります。したがって、3 ^ 5の結合アイコンが生成されます。(通常の場合、3x5の単一アイコンのみ)

    そのため、DejaVu Sansフォントのシンボルでインジケーターラベルを使用しました。

  • アイコンを配置するには、同じフォルダーに配置して名前を付けicon.*ます。使用可能な形式:png、svg、ico、xpm ...

    アイコンが気に入らない場合は、代わりに1x1ピクセルの画像を作成してください。

参照:


いいね、ありがとう!私はこれを試してあなたに戻ってきます。すばらしい仕事、スニーザー!
dotancohen

あなたがっている!
dotancohen

うん、@ dotancohenありがとう。少なくともUnityを使用できますが、固定位置アイコンがないと見苦しいかもしれません。
user.dz 14

1
私はい気にしないでください、あなたは私の写真を見るべきです!この問題はUbuntuバグトラッカーで言及しました
dotancohen

1
スニーター、もう一度ありがとうと言いたかった。私は今、Unityに移行しました。この素晴らしいアプリケーションがなければ、移行は不可能でした。また、コードから多くのことを学びました。ありがとうございました!
-dotancohen

2

完璧ではない別の解決策もありますが、クリックでmodをアクティブ化するなど、KDEのように完全な機能を使用できるため、便利な場合があります。

  1. kbstateアプレットをインストールする

    sudo apt-get install plasma-widget-kbstate kde-workspace-bin
    
  2. plasma-windowedプレーヤーで実行する

    • 通常のウィンドウ

      plasma-windowed kbstate
      

      Xubuntuのplasma-widget-kbstateのスクリーンショット

    • フチ無しウィンドウ

      plasma-windowed --noborder kbstate
      

      Unityのボーダーレスプラズマウィジェットkbstateのスクリーンショット

遊ぶ時間はあまりありませんでしたが、起動時にwmctrl配置、サイズ変更、そしてトップに表示するのに役立つかもしれません。

リファレンス: kdeプラズモイドとキックスタートメニューを起動するコマンド


1

Ubuntuスティッキーキーモニターを検索したところ、ここで役立つ可能性のあるものが見つかりました:http : //code.google.com/p/key-mon/

ケースのスクリーンショットを表示

実行してみてください

key-mon --sticky スティッキーキーのサポート。

参照:http : //code.google.com/p/key-mon/

ソフトウェアセンターから入手できるバージョンは1.6-0ubuntu1です。--stickyスイッチをサポートしない2011年6月にリリース。インジケーターが上記のように見える場合、古いバージョンがあります。これを書いている時点で最新バージョンはhttp://code.google.com/p/key-mon/で試してくださいkeymon_1.17-1_all.deb 229 KBリリース済み2014年1月3日。--stickyスイッチのサポートがテストおよび確認されました。


1
素敵な検索ではkey-monどのボタンが押されたかは示されますが、修飾キーの状態は示さません。違いは、ボタンが押されてから1秒後に、key-monディスプレイが押されていない状態に戻ることです。キーボード修飾子状態アプレットは、次のキー押下が発生したときにディスプレイを非押下状態戻すため、「押下」状態を無効にします。
dotancohen

再編集された回答。
オタク長老

混乱させて申し訳ありません。答えを(もう一度)編集して、必要なものを正確に提供しました。
オタク長老

1
ギーク長老に感謝します。この--stickyオプションは、適切なキーボード修飾子状態アプレットのように適切なインターフェースを照会する代わりに、他のキーの状態を監視することにより、修飾キーの状態を推測するようです。これは、修飾キーを2回押すことで確認できます。1回目はアプレットのインジケータを有効にしますが、2回目はそれをリリースしません。したがって、状態はアクティブでないと誤って報告されます。この関連バグは問題を部分的に解決します。そこで詳細と追加のバグを記入します。ありがとうございました。
dotancohen

1
@dotancohen「キーボードモディファイアステートアプレットは、次のキー押下が発生するとディスプレイを非押下状態に戻すため、「押下」状態を無効にする」というステートメントに基づいてテストしました。そして、だれかが意図的に連続して2回修飾キーを押すことは決して思いつきませんでした。監督に謝罪。
オタク長老
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.