Форум русскоязычного сообщества Ubuntu


Следите за новостями русскоязычного сообщества Ubuntu в Twitter-ленте @ubuntu_ru_loco

Автор Тема: xNeur - Punto Switcher for Linux (Архив)  (Прочитано 653060 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Чистый

  • Почётный модератор
  • Старожил
  • *
  • Сообщений: 3473
  • nix - вот оно счастье...
    • Просмотр профиля
Re: xNeur - Punto Switcher for Linux
« Ответ #3600 : 07 Апреля 2011, 11:53:31 »
Прошу прощения за вчерашнее провокационное сообщение. Накипело просто, да еще и пьян был, вот и высказался.

Разработку я не брошу. Как говорится, назвался груздем - полезай в кузов.
Надеюсь на дальнейшее плодотворное сотрудничество.
Фух... ты так не шути :D, о кстати а Donate как можно сделать? а то у меня где 40-50 уе на webmany завалялись и не знаю куда их спулить а так на благое дело будет пущено :)
Тестовый репозиторий kdeNeur ppa:devcode/kdeneur
各々が死ぬことをどのように決定する

Оффлайн mechanical

  • Активист
  • *
  • Сообщений: 682
    • Просмотр профиля
Re: xNeur - Punto Switcher for Linux
« Ответ #3601 : 07 Апреля 2011, 11:54:44 »
на xneur.ru есть кошельки
Archlinux i686 , Lenovo ThinkPad SL510

Оффлайн Чистый

  • Почётный модератор
  • Старожил
  • *
  • Сообщений: 3473
  • nix - вот оно счастье...
    • Просмотр профиля
Re: xNeur - Punto Switcher for Linux
« Ответ #3602 : 07 Апреля 2011, 12:11:01 »
на xneur.ru есть кошельки

Тема.. вечерком буду вспоминать пароли и явки на webmoney
Тестовый репозиторий kdeNeur ppa:devcode/kdeneur
各々が死ぬことをどのように決定する

Оффлайн catalyst

  • Активист
  • *
  • Сообщений: 475
    • Просмотр профиля
Re: xNeur - Punto Switcher for Linux
« Ответ #3603 : 07 Апреля 2011, 14:03:24 »
мдя... громкое дело чуть было не случилось, хорошо что я вчера не читал эту ветку, тоже изпереживался бы за программу  :)  Андрей то что ты делаешь это просто прекрасно, впервые подсел на Linux пару лет назад ПЕРВОЙ программой которой я сразу же решил обзавестись стал именно xneur, ну за столько лет просто как к наркотику привык к пунтосвитчеру в виндозе! Скажу лишь что прогграма ДЛЯ МЕНЯ нынче работает идеально, все переключает, распознает и т.д. а то что у многих проблемы так это ... это Linux мать его за ногу, миллион дистрибутивов, оболочек, библиотеки разные, руки кривые как у создателей так и юзеров, это нормально что люди находят проблемы, невозможно написать вылизанное до кристальной чистоты приложение на пингвине, либо если напишешь и добавишь новые функции то снова появятся баги, баги, баги...

Мое мнение - не бросай этот замечательный проект, он того стоит. А силы надо беречь, никто не заставляет специалиста по ERP MS торчать за компом и отлаживать бесплатный проект, это должно быть делом души - хочешь делаешь, нет - не делаешь. Еще есть замечательный проект QMMP, обожаю этот плеер и автор молодчина, уже несколько лет каждодневно кодит свою программу и постоянно держит обратную связь с пользователями. А Qbittorent - а автор! я с ним переписывался тот тоже безумно любит свою программу и постоянно совершенствует. Примеров много  ;) продолжай свою работу

Оффлайн CityAceE

  • Активист
  • *
  • Сообщений: 483
  • Ubuntu 18.04 amd64
    • Просмотр профиля
    • Speccy - наш выбор!
Re: xNeur - Punto Switcher for Linux
« Ответ #3604 : 07 Апреля 2011, 15:17:41 »
Тоже хотелось бы выразить почтение автору и сказать большое спасибо за программу, которой я всегда пользуюсь.
С уважением, Станислав.

Оффлайн RussianNeuroMancer

  • Любитель
  • *
  • Сообщений: 84
    • Просмотр профиля
Re: xNeur - Punto Switcher for Linux
« Ответ #3605 : 07 Апреля 2011, 15:19:34 »
Выражать почтение нужно здесь http://xneur.ru/donate/ и на регулярной основе, я считаю.

Оффлайн mechanical

  • Активист
  • *
  • Сообщений: 682
    • Просмотр профиля
Re: xNeur - Punto Switcher for Linux
« Ответ #3606 : 07 Апреля 2011, 15:26:34 »
Выражать почтение нужно здесь http://xneur.ru/donate/ и на регулярной основе, я считаю.
считаешь - выражай
каждый выражает своё почтение так, как считает возможным
Archlinux i686 , Lenovo ThinkPad SL510

Оффлайн 6uest

  • Активист
  • *
  • Сообщений: 302
    • Просмотр профиля
Re: xNeur - Punto Switcher for Linux
« Ответ #3607 : 07 Апреля 2011, 16:27:16 »
Заметил еще - через какоето время отваливается и автодополнение по клавише TAB , при перезапуском демона лечится, клавиша начинает работать, но не долго ... постораюсь поймать этот момент по логам
+1
Проблема появилась только на последней ночной сборке. Раньше не возникало.
Version: 0.12.0+svn880-0maverick

Оффлайн catalyst

  • Активист
  • *
  • Сообщений: 475
    • Просмотр профиля
Re: xNeur - Punto Switcher for Linux
« Ответ #3608 : 07 Апреля 2011, 17:02:27 »
Выражать почтение нужно здесь http://xneur.ru/donate/ и на регулярной основе, я считаю.
считаешь - выражай
каждый выражает своё почтение так, как считает возможным


ибо как даже автор сказал - Добрые слова стоят значительно больше денег! :)

Оффлайн mechanical

  • Активист
  • *
  • Сообщений: 682
    • Просмотр профиля
Re: xNeur - Punto Switcher for Linux
« Ответ #3609 : 07 Апреля 2011, 17:56:48 »
я сегодня надумал 7 качать
отменяется что-ль?
Archlinux i686 , Lenovo ThinkPad SL510

Оффлайн Clr

  • Любитель
  • *
  • Сообщений: 56
    • Просмотр профиля
    • MakeLinux — всё о настройке Linux систем
Re: xNeur - Punto Switcher for Linux
« Ответ #3610 : 08 Апреля 2011, 05:45:49 »
<offtop>
а по ширине оно почти в два раза шире монитора и сузить его нет никакой возможности
Это всё потому, что разработчики тулкита считают себя умнее разработчиков приложений и  пользователей.
</offtop>

Пользователь решил продолжить мысль [time]Fri Apr  8 08:46:10 2011[/time]:

Решил посмотреть, что именно тормозит при конвертировании длинных текстов. Нашел 3 основных источника тормозов:
1. В buffer_set_content вызов keymap->convert_text_to_ascii.
2. Вызов buffer_set_i18n_content там же.
3. Собственно посылка данных в текущее окно.

Пункт 3 игнорируем. Пункт 1 тормозит только при конвертировании рус->лат. Остаётся пункт 2 — основной кандидат на оптимизацию.

buffer_set_i18n_content большую часть времени проводит в keycode_to_symbol.

Патч, реализующий кэширование результатов keycode_to_symbol:
(http://pastebin.com/UtdQzFit)
Index: lib/main/program.c
===================================================================
--- lib/main/program.c (revision 885)
+++ lib/main/program.c (working copy)
@@ -314,6 +314,8 @@
  {
  int type = p->event->get_next_event(p->event);
 
+ purge_keymap_caches();
+
  int curr_layout = get_curr_keyboard_group();
  if ((p->last_layout != curr_layout) && (p->last_window == p->focus->owner_window))
  {
Index: lib/main/keymap.c
===================================================================
--- lib/main/keymap.c (revision 885)
+++ lib/main/keymap.c (working copy)
@@ -67,7 +67,7 @@
  return languages_mask;
 }
 
-char* keycode_to_symbol(KeyCode kc, int group, int state)
+static char* keycode_to_symbol_real(KeyCode kc, int group, int state)
 {
  Display *display = XOpenDisplay(NULL);
  XEvent event;
@@ -148,6 +148,62 @@
  return symbol;
 }
 
+#define keycode_to_symbol_cache_size 64
+static struct keycode_to_symbol_pair {
+ KeyCode kc; int group; int state;
+ char* symbol; size_t symbol_size;
+} keycode_to_symbol_cache[keycode_to_symbol_cache_size];
+size_t keycode_to_symbol_cache_pos = 0;
+
+char* keycode_to_symbol(KeyCode kc, int group, int state)
+{
+ char *symbol;
+ struct keycode_to_symbol_pair *p = NULL;
+
+ /* Look up cache. */
+ for (int i = 0; i < keycode_to_symbol_cache_size; i++) {
+ p = keycode_to_symbol_cache + i;
+ if (p->symbol && p->kc == kc && p->group == group && p->state == state)
+ goto ret;
+ }
+
+ /* Miss. */
+
+ symbol = keycode_to_symbol_real(kc, group, state);
+ if (!symbol)
+ return symbol;
+
+ /* Just use next cache entry. LRU makes no sense here. */
+ keycode_to_symbol_cache_pos = (keycode_to_symbol_cache_pos + 1) % keycode_to_symbol_cache_size;
+
+ p = keycode_to_symbol_cache + keycode_to_symbol_cache_pos;
+
+ p->symbol_size = (strlen(symbol) + 1) * sizeof(char);
+ if (p->symbol)
+ free(p->symbol);
+ p->symbol = symbol;
+ p->kc     = kc;
+ p->group  = group;
+ p->state  = state;
+
+ ret:
+
+ symbol = (char *) malloc(p->symbol_size);
+ memcpy(symbol, p->symbol, p->symbol_size);
+ return symbol;
+}
+
+void purge_keymap_caches(void)
+{
+ for (int i = 0; i < keycode_to_symbol_cache_size; i++) {
+ struct keycode_to_symbol_pair* p = keycode_to_symbol_cache + i;
+ if (p->symbol)
+ free(p->symbol),
+ p->symbol = NULL,
+ p->symbol_size = 0;
+ }
+}
+
 int get_keycode_mod(int group)
 {
  return keyboard_groups[group];
Index: lib/main/keymap.h
===================================================================
--- lib/main/keymap.h (revision 885)
+++ lib/main/keymap.h (working copy)
@@ -28,6 +28,7 @@
 int   get_languages_mask(void);
 void  get_keysyms_by_string(char *keyname, KeySym *Lower, KeySym *Upper);
 char* keycode_to_symbol(KeyCode kc, int group, int state);
+void  purge_keymap_caches(void);
 
 struct _keymap
 {


В качестве политики замещения к кэше используется простейший round robin.
При получении любого сообщения от иксов отрабатывает purge_keymap_caches(), обнуляя кэш. Конечно, лучше её вызывать только при изменении клавиатурных маппингов, но мне лень было искать, откуда правильнее всего это делать.

Проверял на таком тестовом фрагменте:

*
*  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
*
*  Copyright (C) 2006-2010 XNeur Team
*
*

Без патча buffer_set_i18n_content на моём железе отрабатывает за 8 секунд, с патчем — за 1.

convert_text_to_ascii при конвертировании лат->рус не тормозит, при конвертировании рус->лат отрабатывает также за 8 секунд. Планирую туда тоже добавить кэш.


Пользователь решил продолжить мысль [time]Fri Apr  8 08:49:52 2011[/time]:
Также нашел, вероятно, мелкий баг:

Index: lib/main/buffer.c
===================================================================
--- lib/main/buffer.c (revision 885)
+++ lib/main/buffer.c (working copy)
@@ -311,7 +311,7 @@
  continue;
 
  char *symbol_unchanged = keycode_to_symbol(p->keycode[k], i, modifier);
- if (symbol == NULL)
+ if (symbol_unchanged == NULL)
  continue;
 
  p->i18n_content[i].content = (char *) realloc(p->i18n_content[i].content, (strlen(p->i18n_content[i].content) + strlen(symbol) + 1) * sizeof(char));
« Последнее редактирование: 08 Апреля 2011, 09:02:37 от Clr »

Оффлайн Crew

  • Автор темы
  • Старожил
  • *
  • Сообщений: 1384
  • xneur 0.20.0
    • Просмотр профиля
Re: xNeur - Punto Switcher for Linux
« Ответ #3611 : 08 Апреля 2011, 12:52:17 »
Добавил патч, сброс кеша поставил на событие Mapping Notify.
PPA cо стабильными сборками xneur: ppa:andrew-crew-kuznetsov/xneur-stable
PPA c "ночными" сборками xneur: ppa:andrew-crew-kuznetsov/xneur-unstable

Оффлайн Clr

  • Любитель
  • *
  • Сообщений: 56
    • Просмотр профиля
    • MakeLinux — всё о настройке Linux систем
Re: xNeur - Punto Switcher for Linux
« Ответ #3612 : 08 Апреля 2011, 13:51:41 »
Попробовал немного модифицировать keymap.c. Внёс изменения в keymap_get_ascii и keymap_convert_text_to_ascii, удалил char_to_keycode. Что получилось:

* Преобразование текстового символа в кейкод выполняется полностью в keymap_get_ascii, char_to_keycode удалена как избыточная. (Она, конечно, для частного случая работает быстрее keymap_get_ascii, но кэш должен будет эту проблему решить.)
* Из keymap_convert_text_to_ascii убрал избыточный вложенный цикл.
* keymap_get_ascii проводит сначала поиск по "предпочтительной" раскладке, а затем по всем остальным. А также возвращает код раскладки, в которой найден символ. В свою очередь, keymap_convert_text_to_ascii передаёт в keymap_get_ascii "предпочтительную" раскладку, равную раскладке от предыдущего символа.  Это позволяет не путать символы, находящиеся в нескольких раскладках на различных клавишах. Например, "qwerty.,:;йцукен.,:;" конвертируется в "йцукенюбЖжqwerty/?^$" и обратно без смешивания кейкодов знаков препинания в одну кучу.
Данная фича может вызывать неожиданное поведение в случаях вида "qб" -> "й," -> "q?" -> "й,", но тут уже ничего не поможет, кроме телепатии.
Наверное, тут надо предусмотреть опцию в настройках для переключения старого/нового поведения.

Если сегодня-завтра время найдётся, прикручу кэш вокруг keymap_get_ascii.

Index: lib/main/keymap.c
===================================================================
--- lib/main/keymap.c (revision 886)
+++ lib/main/keymap.c (working copy)
@@ -273,16 +273,18 @@
  return TRUE;
 }
 
-static void keymap_char_to_keycode(struct _keymap *p, char ch, KeyCode *kc, int *modifier)
+static char keymap_get_ascii(struct _keymap *p, const char *sym, int* preferred_lang, KeyCode *kc, int *modifier, size_t* symbol_len)
 {
  Display *display = XOpenDisplay(NULL);
-
- if (ch == 10 || ch == 13)
+
+ if (*sym == 10 || *sym == 13)
  {
  *kc = XKeysymToKeycode(display, XK_Return);
  *modifier = 0;
+ if (symbol_len)
+ *symbol_len = 1;
  XCloseDisplay(display);
- return;
+ return *sym;
  }
 
  XEvent event;
@@ -295,53 +297,21 @@
  event.xkey.state = 0;
  event.xkey.keycode = XKeysymToKeycode(display, XK_space);
  event.xkey.time = CurrentTime;
-
- char *symbol = (char *) malloc((256 + 1) * sizeof(char));
-
- for (int i = p->min_keycode + 1; i <= p->max_keycode; i++)
- {
- event.xkey.keycode = i;
- event.xkey.state = 0;
-
- int nbytes = XLookupString((XKeyEvent *) &event, symbol, 256, NULL, NULL);
- if ((nbytes > 0) && (symbol[0] == ch))
- break;
-
- event.xkey.state = ShiftMask;
-
- nbytes = XLookupString((XKeyEvent *) &event, symbol, 256, NULL, NULL);
- if ((nbytes > 0) && (symbol[0] == ch))
- break;
- }
-
- *kc = event.xkey.keycode;
- *modifier = (event.xkey.state == ShiftMask) ? 1 : 0;
- free(symbol);
 
- XCloseDisplay(display);
-}
-
-static char keymap_get_ascii(struct _keymap *p, const char *sym, KeyCode *kc, int *modifier)
-{
- Display *display = XOpenDisplay(NULL);
- XEvent event;
- event.type = KeyPress;
- event.xkey.type = KeyPress;
- event.xkey.root = RootWindow(display, DefaultScreen(display));
- event.xkey.subwindow = None;
- event.xkey.same_screen = True;
- event.xkey.display = display;
- event.xkey.state = 0;
- event.xkey.keycode = XKeysymToKeycode(display, XK_space);
- event.xkey.time = CurrentTime;
-
  char *symbol = (char *) malloc((256 + 1) * sizeof(char));
  char *prev_symbols = (char *) malloc((256 + 1) * sizeof(char));
 
- for (int lang = 0; lang < p->handle->total_languages; lang++)
+ int _preferred_lang = 0;
+ if (preferred_lang)
+ _preferred_lang = *preferred_lang;
+
+ for (int _lang = 0; _lang < p->handle->total_languages; _lang++)
  {
- if (lang == p->latin_group)
- continue;
+ int lang = _lang;
+ if (lang == 0)
+ lang = _preferred_lang;
+ else if (lang <= _preferred_lang)
+ lang--;
 
  KeySym *keymap = p->keymap;
  for (int i = p->min_keycode; i <= p->max_keycode; i++)
@@ -379,6 +349,8 @@
  if (strncmp(sym, symbol, strlen(symbol)) != 0)
  continue;
 
+ size_t _symbol_len = strlen(symbol);
+
  event.xkey.state = 0;
  event.xkey.state |= state_masks[m];
  event.xkey.state |= state_masks[n];
@@ -393,6 +365,10 @@
  free(symbol);
  *kc = event.xkey.keycode;
  *modifier = get_keycode_mod(lang) | event.xkey.state;
+ if (symbol_len)
+ *symbol_len = _symbol_len;
+ if (preferred_lang)
+ *preferred_lang = lang;
  XCloseDisplay(display);
  return sym;
  }
@@ -441,27 +417,16 @@
  int text_len = strlen(text);
 
  int j = 0;
- for (int i = 0; i < text_len; i++)
+ size_t symbol_len = 0;
+ int preferred_lang = 0;
+ for (int i = 0; i < text_len; i += symbol_len)
  {
- if (isascii(text[i]) || isspace(text[i]))
- {
- p->char_to_keycode(p, text[i], &kc[j], &kc_mod[j]);
- text[j++] = text[i];
- continue;
- }
+ char new_symbol = p->get_ascii(p, &text[i], &preferred_lang, &kc[j], &kc_mod[j], &symbol_len);
 
- char new_symbol = p->get_ascii(p, &text[i], &kc[j], &kc_mod[j]);
-
- for(; i < text_len - 1; i++)
- {
- if (isascii(text[i + 1]) || isspace(text[i + 1]))
- break;
-
- if (p->get_ascii(p, &text[i + 1], &kc[i + 1], &kc_mod[i + 1]) != NULLSYM)
- break;
- }
-
- text[j++] = new_symbol;
+ if (new_symbol != NULLSYM && symbol_len > 0)
+ text[j++] = new_symbol;
+ else
+ symbol_len = 1;
  }
 
  text[j] = NULLSYM;
@@ -623,7 +588,6 @@
  p->get_ascii = keymap_get_ascii;
  p->get_cur_ascii_char = keymap_get_cur_ascii_char;
  p->convert_text_to_ascii = keymap_convert_text_to_ascii;
- p->char_to_keycode = keymap_char_to_keycode;
  p->lower_by_keymaps = keymap_lower_by_keymaps;
  p->uninit = keymap_uninit;
 
Index: lib/main/keymap.h
===================================================================
--- lib/main/keymap.h (revision 886)
+++ lib/main/keymap.h (working copy)
@@ -46,10 +46,9 @@
  unsigned int scrolllock_mask;
  unsigned int capslock_mask;
 
- char  (*get_ascii)(struct _keymap *p, const char *sym, KeyCode *kc, int *modifier);
+ char  (*get_ascii)(struct _keymap *p, const char *sym, int* preferred_lang, KeyCode *kc, int *modifier, size_t* symbol_len);
  char  (*get_cur_ascii_char) (struct _keymap *p, XEvent e);
  void  (*convert_text_to_ascii)(struct _keymap *p, char *text, KeyCode *kc, int *kc_mod);
- void  (*char_to_keycode)(struct _keymap *p, char ch, KeyCode *kc, int *modifier);
  void  (*print_keymaps)(struct _keymap *p);
  char* (*lower_by_keymaps)(struct _keymap *p, int gr, char *text);
  void  (*uninit) (struct _keymap *p);

Оффлайн Crew

  • Автор темы
  • Старожил
  • *
  • Сообщений: 1384
  • xneur 0.20.0
    • Просмотр профиля
Re: xNeur - Punto Switcher for Linux
« Ответ #3613 : 08 Апреля 2011, 14:41:00 »
Залил в svn 887.
PPA cо стабильными сборками xneur: ppa:andrew-crew-kuznetsov/xneur-stable
PPA c "ночными" сборками xneur: ppa:andrew-crew-kuznetsov/xneur-unstable

Оффлайн mehanoid

  • Участник
  • *
  • Сообщений: 149
  • Arch Linux user
    • Просмотр профиля
Re: xNeur - Punto Switcher for Linux
« Ответ #3614 : 08 Апреля 2011, 15:11:49 »
Заметил такую странность: если открыть диалог запуска программ (krunner, по умолчанию вызывается по alt+F2), после этого почему-то xneur не переключает раскладки, как автоматически, так и выделенный текст, до тех пор, пока я не перезапущу xneur
В данный момент стоит xneur версии svn885, KDE 4.6.2

 

Страница сгенерирована за 0.021 секунд. Запросов: 19.