키보드 수정 자 상태 애플릿을 Unity 패널에 추가하는 방법은 무엇입니까?


18

Unity로 전환하는 것을 생각하는 KDE 사용자입니다. 수동 장애로 인해 스티커 키를 사용 하고 KDE에서는 활성화 된 수정 자 키를 보여주는 애플릿이 시스템 패널에 있습니다. 그놈도이 기능을 가지고 있다는 것을 기억합니다. Windows와 OS X도 마찬가지입니다.

키보드 수정 자 상태 애플릿을 Unity의 패널에 어떻게 적용합니까?

설명 : 스티커 키를 이미 활성화했습니다. 수정 자 키의 상태나타내는 애플릿을 추가하는 방법을 묻습니다 . 이 표시기는 Shift 키를 누를 때, Alt 키를 누를 때, Tux 키를 누를 때 및 Ctrl 키를 누를 때 나타납니다. 이 애플릿은 모든 주요 데스크탑 환경 (KDE, Windows, Mac OSX 및 Gnome)에 존재합니다. 데스크탑의 접근성을 위해 필요합니다.

다음은 키보드 레이아웃 표시기 애플릿 옆에있는 키보드 수정 자 상태 애플릿의 이미지입니다. 나타내는 수식은 왼쪽에서있는 권리, Shift, Ctrl, Alt, I-dont-know-this-one, Tux/Win, NumLock,와 CapsLock. NumLock 키가 활성화되어 있음을 알 수 있습니다.

여기에 이미지 설명을 입력하십시오


Errr ... 이것에 관해서는 큰 차이가있는 것 같습니다 ... 수정 자 키를 눌렀을 때 경고음이납니다.
윌프

@wilf 내가 실수하지 않으면 Unity에 접근성 아이콘 (Gnome 3과 동일)이 있지만 사용자에게 상태를 알려주는 "추가"아이콘은 없습니다.
Braiam

4
@Takkat : 제안 해 주셔서 감사합니다. indicator-keylock단지 전통적으로 키보드 자체에 상태 표시 등이 그 키의 상태를 표시합니다 CapsLock, ScrollLock, NumLock. 나는 표준 수식 키의 상태를 보여주는 지표가 필요합니다 Shift, Ctrl, Tux, Alt. 모든 주요 데스크탑 (KDE, Windows, Mac OSX)에는이 표시기 애플릿이 있습니다.
dotancohen

1
나는 당신이 언급하고있는 KDE 툴의 패킷 이름이 plasma-widget-kbstate있고 소프트웨어 센터에서의 빠른 검색은 실제로 동등한 결과에주의를 기울이지 않는다고 생각합니다
Daniel 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

참조 : 키보드 수정 자 상태 표시기 우분투 : Xkbmod 표시기


원래 답변 :

이 질문에 대한 정식 답변에는 참석하지 않습니다. 해결 방법으로 계산 될 수 있습니다. 누군가를 호핑하면 정교한 솔루션이 작성됩니다.

Unity 용 간단한 프로토 타입 키보드 수정 자 표시기입니다.

왼쪽부터 시작하는 이미지 : 아이콘, Shift, 잠긴 캡, 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 지표에는 다른 데스크탑 지표를 쉽게 이식 할 수있는 중요한 기능이 없습니다. 버그 # 812067 API 필요 : pixbuf 아이콘 설정 지원 참조

    이 기능이 없으면 고정 키가 활성화 된 상태에서 (Shift, Ctrl, Alt, AltGr, Super)가 필요하다고 가정합니다. 각각에 대해 3 가지 주요 상태가 있습니다 (Off, On / Latched, Locked). 따라서 3 ^ 5 개의 결합 된 아이콘이 생성되어야합니다. (일반적인 경우 3x5 단일 아이콘 만 해당)

    그렇기 때문에 DejaVu Sans 글꼴의 기호와 함께 표시기 레이블을 사용했습니다 .

  • 아이콘을 넣으려면 아이콘을 같은 폴더에 놓고 이름을 지정하십시오 icon.*. 허용되는 형식 : png, svg, ico, xpm ...

    아이콘이 마음에 들지 않으면 1x1 px 이미지를 대신 만드십시오.

참고 문헌 :


감사합니다! 나는 이것을 시도하고 당신에게 돌아올 것입니다. 훌륭합니다, 스 니터!
dotancohen

당신이 스니커라고!
dotancohen

네, @dotancohen 감사합니다. 적어도 Unity를 사용할 수 있습니다. 고정 위치 아이콘이 없으면 못생긴 것일까 요?
user.dz

1
나는 추악한 상관 없어, 당신은 내 사진을 볼 수 있습니다! 우분투 버그 추적기 에서이 문제를 언급했습니다 .
dotancohen

1
스 니터, 다시 한 번 감사드립니다. 나는 이제 Unity로 옮겼으며이 훌륭한 응용 프로그램이 없으면 이동이 불가능했을 것입니다. 또한 코드에서 많은 것을 배웠습니다. 감사합니다!
dotancohen

2

완벽하지는 않지만 다른 솔루션은 클릭으로 모드를 활성화하는 것과 같이 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

우분투 스티커 키 모니터를 검색하여 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 일.-스티커 스위치 테스트 지원 및 확인.


1
그러나 찾기 기능 key-mon어떤 버튼을 눌렀 는지 , 수정 자 키의 상태가 아님을 보여줍니다 . 구별은 버튼을 누른 후 1 초 후에key-mon 디스플레이가 누르지 않은 상태로 돌아 간다는 것 입니다. 키보드 수정 자 상태 애플릿은 다음 키 누르기가 발생할 때 디스플레이를 누르지 않은 상태로 되돌리고 '눌린'상태를 비활성화합니다 .
dotancohen

재 편집 된 답변.
Geek

혼란을 드려 죄송합니다. 필요한 것을 정확하게 제공하기 위해 답을 다시 편집했습니다.
Geek

1
eek 장로님 감사합니다. 이 --sticky옵션은 적절한 키보드 수정 자 상태 애플릿과 같이 적절한 인터페이스를 쿼리하는 대신 다른 키 상태를 보면서 수정 자 키의 상태를 추측하는 것 같습니다. 수정 자 키를 두 번 누르면 알 수 있습니다. 처음은 애플릿의 표시기를 활성화하지만 두 번째는 해제하지 않습니다. 따라서 상태가 활성화되지 않은 경우 상태가 잘못보고됩니다. 이 관련 버그 는 문제를 부분적으로 해결하므로 자세한 내용과 추가 버그를 작성하겠습니다. 감사합니다.
dotancohen

1
@dotancohen 저는 "키보드 수정 자 상태 애플릿은 다음 키 누르기가 발생할 때 디스플레이를 누르지 않은 상태로 되돌려 서 '눌린'상태를 비활성화합니다." 그리고 누군가가 의도적으로 수정 자 키를 두 번 연속으로 누르는 것은 결코 나에게 새벽이 아닙니다. 감독에 대한 사과드립니다.
Geek
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.