Linux на оборудовании Mac: как убрать задержку блокировки заглавных букв на алюминиевой клавиатуре Apple MacBook Pro при загрузке в Linux

MacBook Pro от Apple имеет небольшую задержку нажатия клавиши Caps Lock . То есть клавишу Caps Lock необходимо удерживать немного дольше, чем обычно, чтобы зарегистрировать нажатие клавиши, необходимое для включения Caps Lock.

Это очень раздражает. Кто-нибудь знает, как предотвратить это?

(Выше скопировано из stackoverflow , поскольку оно было закрыто там как «не по теме».)

Чтобы уточнить: Apple считает это функцией, и в их статье базы знаний не раскрывается, как отключить эту задержку.

Однако у меня есть основания полагать, что это возможно.

Примечательно, что я обнаружил, что, по крайней мере, по моему опыту, если вы переназначите клавишу Caps-Lock в Mac OS X (в Системных настройках .. Клавиатура .. Клавиши-модификаторы) и, например, сопоставите ее с Control, то задержка исчезнет пока я вошел в Mac OS X.

Моя проблема в том, что задержка сохраняется, когда я загружаюсь в Ubuntu Linux, и в этом контексте, даже когда я переназначаю клавишу Caps Lock на Control, задержка все еще присутствует.

Итак, возникает вопрос: как Apple отключает задержку и, что более важно, как можно воспроизвести это действие в контексте установки Linux на ноутбуке?

Обновление: на суперпользователе есть поток , который может предоставить обходные пути. Я еще не пробовал предложенные там предложения (а именно: (1) включение/выключение CapsLock-NoAction и (2) обновление прошивки). Я не могу сказать из контекста этого потока, были ли проверены обходные пути на установке Ubuntu.

Я никогда раньше этого не замечал, но я поиграл со своим, и я понимаю, что вы имеете в виду. Если вы слишком быстро нажмете на клавишу Caps Lock, ничего не произойдет. Раньше я никогда не считал это проблемой, но только что попробовал отключить / снова включить трюк с клавишей Caps Lock, и он сделал это мгновенно! теперь, независимо от того, как быстро я нажимаю клавишу, она всегда переключает заглавные буквы. Очень странно!
Всегда думал, что просто схожу с ума :p Я вижу его пользу, но в некоторых ситуациях он меня действительно раздражает. Было бы неплохо узнать, если это возможно!
Действительно, трюк с отключением/повторным включением заглавных букв (на стороне Mac OS X), кажется, действительно устраняет проблему после последующей перезагрузки в Linux. Но мне не ясно, является ли эффект постоянным — я оставил свою машину выключенной на некоторое время (недели или, может быть, даже больше месяца), и когда я сегодня утром загрузил ее прямо в Linux, мне показалось, что задержка вернулась. Все еще довольно загадочно для меня.
Итак, просто чтобы проверить, похоже, для Linux нет решения этой проблемы?
Я еще не нашел ни одного. в последнее время не искал исправление, но теперь я собираюсь чаще запускать Linux изначально (а не на виртуальной машине, где проблема не возникает), чтобы я мог использовать rrдля отладки, и поэтому, возможно, я еще раз попытаюсь найти исправление.
Вот исправление, которое работает для macOS и может быть запущено под macOS.
Я не удивлюсь, если 99% жертв этой «особенности» даже не подозревают, что это происходит. Первые 10 или около того раз это произошло, я думал, что это моя вина, пока я не начал экспериментировать с нажатием кнопки. Это худшая часть этой «особенности»; это буквально заставляет людей думать, что они плохо печатают.

Ответы (9)

Я придумал, как это сделать. Короче говоря, вы должны отправить «Отчет о функциях», состоящий из байтов 0x9, 0x0, 0x0, 0x0, на соответствующее устройство hidraw от имени пользователя root.

Вы можете найти нужное устройство hidraw с помощью этой команды:

dmesg | grep Apple | grep Keyboard | grep input0 | tail -1 | sed -e 's/.*hidraw\([[:digit:]]\+\).*/\/dev\/hidraw\1/'

Код для отправки пакета управления Magic приведен ниже. Компилируется с помощью gcc, принимает в качестве параметра устройство hidraw. Итак, весь поток:

  1. сохраните код ниже какdisable-capslock-delay.c
  2. gcc -o disable-capslock-delay disable-capslock-delay.c
  3. HIDDEVICE=$(dmesg | grep Apple | grep Keyboard | grep input0 | tail -1 | sed -e 's/.*hidraw\([[:digit:]]\+\).*/\/dev\/hidraw\1/')
  4. sudo ./disable-capslock-delay $HIDDEVICE

Шаги 3 и 4 необходимо выполнять каждый раз при перезагрузке (или отключении и повторном подключении клавиатуры); вы можете поместить их /etc/rc.local(или эквивалент вашего дистрибутива), чтобы выполнять их при загрузке (в этом случае вам это не нужно sudo; и вы можете переместить скомпилированный двоичный файл /usr/local/sbin/или что-то еще).

Я провел некоторые проверки безопасности для идентификатора поставщика, идентификатора устройства и длины дескриптора отчета. Возможно, вам придется изменить последние два, если ваша модель отличается от моей.


#include <linux/hidraw.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
  if (argc != 2 || strcmp(argv[1], "-h") == 0) {
    printf("Pass a hidraw device as the first and only parameter!\n");
    printf("You may find the right device with:\n");
    printf("  dmesg | grep Apple | grep Keyboard | grep input0 | tail -1 | "
           "sed -e 's/.hidraw\([[:digit:]]\+\)./\/dev\/hidraw\1/'\n");
    return 1;
  }
  int fd, i, res, desc_size = 0;
  char buf[256];
  struct hidraw_devinfo info;
  char *device = argv[1];
  fd = open(device, O_RDWR | O_NONBLOCK);
  if (fd < 0) {
    perror("Unable to open device");
    return 1;
  }
  memset(&info, 0, sizeof(info));
  memset(buf, 0, sizeof(buf));
  // Get Report Descriptor Size
  res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size);
  if (res < 0) {
    perror("HIDIOCGRDESCSIZE");
  }
  if (desc_size != 75) {
    printf("Error: unexpected descriptor size %d; you've probably got "
           "the wrong hidraw device!\n", desc_size);
    return 1;
  }
  // Get Raw Info
  res = ioctl(fd, HIDIOCGRAWINFO, &info);
  if (res < 0) {
    perror("HIDIOCGRAWINFO");
  } else {
    if (info.vendor != 0x05ac) {
      printf("Error: Wrong vendor ID, make sure you got the right "
             "hidraw device!\n");
      return 1;
    }
    if (info.product != 0x0250) {
      printf("Warning: Unknown product ID 0x%x!\n", info.product);
    }
  }
  // Get Feature
  buf[0] = 0x09;  // Report Number
  res = ioctl(fd, HIDIOCGFEATURE(256), buf);
  if (res < 0) {
    perror("HIDIOCGFEATURE");
  } else {
    printf("HID Feature Report (before change):\n\t");
    for (i = 0; i < res; i++) printf("%hhx ", buf[i]);
    puts("\n");
  }
  // Set Feature
  buf[0] = 0x09;  // Report Number
  buf[1] = 0x00;  // Report data
  buf[2] = 0x00;  // padding
  buf[3] = 0x00;  // padding
  res = ioctl(fd, HIDIOCSFEATURE(4), buf);
  if (res < 0) {
    perror("HIDIOCSFEATURE");
  } else {
    printf("Caps lock delay disabled.\n");
  }
  // Get Feature
  buf[0] = 0x09;  // Report Number
  res = ioctl(fd, HIDIOCGFEATURE(256), buf);
  if (res < 0) {
    perror("HIDIOCGFEATURE");
  } else {
    printf("HID Feature Report (after change):\n\t");
    for (i = 0; i < res; i++) printf("%hhx ", buf[i]);
    puts("\n");
  }
  close(fd);
  return 0;
}

Это выглядит великолепно, спасибо! из интереса, как вы это нашли (магические байты, необходимые для отправки)?
@MikeH-R: Я провел день, изучая, как работает протокол HID: по сути, устройства описывают, какие пакеты данных («отчеты») они понимают. К сожалению, клавиатура Apple не упоминает рассматриваемый отчет в своих дескрипторах HID. Однако я нашел дамп дескрипторов HID внутренней клавиатуры MacBook, который кто-то опубликовал, который действительно содержал правильное описание отчета, и я просто попробовал это и обнаружил, что он работает и для внешней проводной клавиатуры.
Ого, я должен попробовать это!
(Кажется, я получаю, по крайней мере, разные размеры дескрипторов. Тем не менее я их настрою и посмотрю, как это работает.)
Я собираюсь принять этот ответ, потому что он наиболее близок к фактическому признанию проблемы, как описано, и предоставлению правдоподобного решения (хотя в моем случае размеры дескриптора другие).
Ух ты. И тебе, Apple!
[Здесь][1] — ваш код исправления, перенесенный на macOS. [1]: apple.stackexchange.com/questions/284899/…

Вот исправление для macOS Sierra.

Перейдите в Системные настройки > Специальные возможности.

Когда окно специальных возможностей открыто — в левой части окна — нажмите Клавиатура

Затем будет 2 варианта — для залипания клавиш и для медленных клавиш — щелкните поле рядом с медленными клавишами, чтобы включить его — затем нажмите Options...кнопку — появится новое окно с ползунком для изменения задержки принятия — по умолчанию это в середине. Сдвиньте кнопку до упора влево, чтобы это было как можно короче.

Теперь это должно быть исправлено. Не экспериментировал, чтобы увидеть, останется ли исправление после перезапуска, но я надеюсь, что это произойдет.

Я был взволнован на секунду, но когда я пошел посмотреть здесь, медленные клавиши не были включены, поэтому работают только для людей, которые используют медленные клавиши :( однажды я верну свою драгоценную клавишу Caps Lock!
Это немного уменьшает его, но по-прежнему медленнее включать Caps-Lock, чем выключать. Кроме того, частота повторения клавиш снижается до минимума, даже если для параметра установлено значение «Самое быстрое». (Сьерра 10.12.6)
это не правильное решение проблемы, так как это замедляет восстановление ключей, и вы больше не можете правильно удалять вещи, удерживая клавишу Backspace.
В Монтерее это работает

РЕДАКТИРОВАТЬ: Это, кажется, популярный вопрос для пользователей, которые хотят удалить задержку клавиши Caps Lock в OS X. Что касается OS X Mojave,

Перейдите в Системные настройки; доступность; Клавиатура; включить медленные клавиши и перейти к параметрам; уменьшите задержку до минимума. Единственный нежелательный побочный эффект, который я заметил до сих пор, — это медленное нажатие на клавишу Backspace при удерживании ее нажатой. Обычно я использую CMD+A / CMD+SHIFT+L/R / CMD+SHIFT+CTRL+L/R в любом случае, так что это не большая проблема.

Начиная с Эль-Капитана и ранее,

Решение довольно неуловимое, и вы бы не узнали, что удалили его, если бы не пытались избавиться от него специально. Способ, который я собираюсь вам показать, предназначен исключительно для (текущей) последней версии OSX, Yosemite. Однако вы можете абсолютно точно применить этот метод к предыдущим и будущим версиям.

Решение простое. Если вы перейдете к клавиатуре в настройках системы через логотип Apple в верхнем левом углу, вы попадете на этот экран.

введите описание изображения здесь

Если вы нажмете кнопку клавиши-модификатора, вы сможете изменить функцию каждой из программируемых клавиш. Все, что вам нужно сделать, это установить клавишу Caps Lock без действия и нажать ОК, чтобы вернуться в меню клавиатуры. После этого вернитесь к клавишам-модификаторам и измените клавишу Caps Lock обратно на Caps Lock, и это устранит задержку! Обратите внимание, что это исправление остается в силе до тех пор, пока вы не перейдете в спящий режим, не перезапустите или не выключите устройство. В этот момент задержка восстанавливается.

Это странные исправления, и возникает вопрос, почему они не предоставляют возможность удалить задержку, когда это исправление основано исключительно на программном обеспечении. Но эй, по крайней мере, есть способ!

Удачного укупорки.

Как это решает мою проблему в Linux?
Чтобы быть яснее: исходный вопрос гласил: «... задержка исчезает, когда я вхожу в Mac OS X. Моя проблема в том, что задержка остается, когда я загружаюсь в Ubuntu Linux, и в этом контексте, даже когда я переназначаю Клавиша Caps Lock на Control, задержка все равно присутствует."
Ах! Понятно, думаю, мне следует более внимательно читать вопросы ОП. Я обнаружил в OSX, что полная отвязка клавиши заглавных букв и повторная привязка решили проблему. Может быть, задержка остается, потому что вместо этого вы привязываетесь к контролю? Стоит попробовать все, если у вас еще нет работы :)
Этот подход не имел никакого эффекта для меня. (Сьерра 10.12.6)

Работа над ответом @jmrk. Его код хорошо работает для так называемой «алюминиевой» клавиатуры, но Apple также выпускала беспроводные клавиатуры под названием «волшебная клавиатура» с идентификатором продукта 0x022d. (У них также есть алюминиевое шасси, и я думаю, что моя модель примерно 2008 года.) У этого продукта такая же проблема с заглавными буквами, и почти такой же код может ее исправить. Помимо изменения идентификатора продукта, размер дескриптора равен 218, а данные для отправки — не 0x00, а 0x01:

buf[0] = 0x09;  // Report Number
buf[1] = 0x01;  // Report data

Я нашел это сегодня и решил записать свой ответ здесь на случай, если он кому-нибудь поможет, включая меня в будущем.

Вот полная программа, устраняющая проблему на обоих типах устройств. Вы можете передать дополнительные скрытые устройства, это будет применяться только к известным. Таким образом, вы можете просто назвать это как./a.out /dev/hidraw*

#include <linux/hidraw.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv) {
  printf("Pass all devices to configure. For example, like this: %s /dev/hidraw*\n", argv[0]);
  int expected_desc_size;
  char data_to_set;
  for (int argnum=1;argnum<argc;argnum++) {
    printf("Trying to configure %s...\n", argv[argnum]);
    
    int fd, i, res, desc_size = 0;
    char buf[256];
    struct hidraw_devinfo info;
    char *device = argv[argnum];
    fd = open(device, O_RDWR | O_NONBLOCK);
    if (fd < 0) {
      perror("Unable to open device");
      return 1;
    }
    memset(&info, 0, sizeof(info));
    memset(buf, 0, sizeof(buf));
    
    // Get Raw Info
    res = ioctl(fd, HIDIOCGRAWINFO, &info);
    if (res < 0) {
      perror("HIDIOCGRAWINFO");
      return 1;
    }
    if (info.vendor == 0x05ac) {
      printf("Apple device found!\n");
    } else {
      printf("Not an apple device.\n");
      continue;
    }
    if (info.product == 0x022d) {
      printf("We have a 'magic' keyboard\n");
      expected_desc_size = 218;
      data_to_set = 1;
    } else if (info.product == 0x0250) {
      printf("We have an 'aluminium' keyboard\n");
      expected_desc_size = 75;
      data_to_set = 0;
    }
    else {
      printf("Warning: Unknown product ID 0x%x!\n", info.product);
      continue;
    }
    // Get Report Descriptor Size
    res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size);
    if (res < 0) {
      perror("HIDIOCGRDESCSIZE");
      return 1;
    }
    if (desc_size != expected_desc_size) {
      printf("Error: unexpected descriptor size %d; panic'ing", desc_size);
      return 1;
    }
    // Get Feature
    buf[0] = 0x09;  // Report Number
    res = ioctl(fd, HIDIOCGFEATURE(256), buf);
    if (res < 0) {
      perror("HIDIOCGFEATURE");
    } else {
      printf("HID Feature Report (before change):\n\t");
      for (i = 0; i < res; i++) printf("%hhx ", buf[i]);
      puts("\n");
    }
      
    // Set Feature
    buf[0] = 0x09;  // Report Number
    buf[1] = data_to_set;  // Report data
    buf[2] = 0x00;  // padding
    buf[3] = 0x00;  // padding
    res = ioctl(fd, HIDIOCSFEATURE(4), buf);
    if (res < 0) {
      perror("HIDIOCSFEATURE");
    } else {
      printf("Caps lock delay disabled.\n");
    }
    // Get Feature
    buf[0] = 0x09;  // Report Number
    res = ioctl(fd, HIDIOCGFEATURE(256), buf);
    if (res < 0) {
      perror("HIDIOCGFEATURE");
      return 1;
    } 
    printf("HID Feature Report (after change):\n\t");
    for (i = 0; i < res; i++) printf("%hhx ", buf[i]);
    puts("\n");
    close(fd);
    }
  return 0;
}
Спасибо огромное! Если бы вы хотели отредактировать это в конце принятого ответа или лучше - в потоке, чтобы вызвать два кода для разных устройств, я бы одобрил это редактирование.
@bmike Я обновил программу, чтобы она стала более гибкой, что привело бы к большому количеству правок в оригинале. Поэтому я просто отредактировал свой ответ, чтобы добавить код. Как только мы убедимся, что это хорошо работает для большего количества людей, еще будет время улучшить лучший ответ.
Я бы снова +1, но я получаю только один голос - хорошо сделано - теперь это может быть намного лучше.
Когда я искал способ отключить эту надоедливую задержку, я ожидал довольно много ручной работы. Я не ожидал, что кто-то преподнесет мне удобный код на блюдечке!

Я точно знаю, что задержка Caps Lock является особенностью прошивки самой клавиатуры, поэтому вы можете быть уверены, что время задержки происходит независимо от того, какая ОС работает на клавиатуре в данный момент.

Я также знаю, что Apple не предлагает путь для прошивки прошивки до более низкого уровня, поэтому нам всем придется ждать, пока кто-то с достаточным опытом работы с аппаратным обеспечением не опубликует в блогах инструменты и шаги, которые они выполнили, чтобы обманом заставить оборудование загрузить более старую прошивку (или предоставить то, что выглядит как более новая прошивка, которая регрессирует задержку к тому, как она работала раньше, без каких-либо задержек.)

Прошу прощения за отсутствие ответа, но путь к этому хорошо освещен, и это может помочь другим принять меры (выбрать более старую клавиатуру или воздержаться от обновления прошивки) в то же время, пока мы ждем реального решения для реализации короткий таймер или его отсутствие на клавише Caps Lock.

Одна деталь, которая меня смущает в вашем ответе: вы говорите, что неверно, что при переназначении клавиши Caps-Lock в Mac OS X задержка исчезает? (Я не знаю, как еще интерпретировать ваше утверждение «время задержки происходит независимо от того, какую ОС использует клавиатура в данный момент»; но это противоречит моему непосредственному опыту — если только Apple не использует какой-то недокументированный API к прошивке для настройки сроки?)
Я переназначил свой на ESC, и немного более длительное удержание все еще необходимо. Я сделал это с помощью стороннего приложения под названием Seil, а не с помощью каких-либо функций, встроенных в OSX. Раздражает, конечно, — разве их разработчики не используют Vim? Боже.

Перейдите в системные настройки> специальные возможности> клавиатура> включите медленные клавиши> измените задержку приема полностью влево (коротко)! Это сработало для меня.

Вы описываете шаг в Mac OS X? Как это решает проблему в Ubuntu Linux, как описано в вопросе?
Да исправить. Я не знаю Ubuntu Linux, извините. Я думаю, что решаю основной заголовок «Как убрать задержку Caps Lock на алюминиевой клавиатуре Apple MacBook Pro*» и, возможно, вопрос «Как Apple отключает задержку». :-) С наилучшими пожеланиями Томас, Швеция *Этот вопрос - причина, по которой я нашел и прочитал этот протектор, и ничего не помогло, поэтому я решил его сам: P
Согласно ответу Мишель: это немного уменьшает его, но все же медленнее включать Caps-Lock, чем выключать. Кроме того, частота повторения клавиш снижается до минимума, даже если для параметра установлено значение «Самое быстрое». (Сьерра 10.12.6)

Решение «включение/выключение CapsLock-NoAction», на которое ссылается OP, работает как на моей проводной клавиатуре Mac, так и на клавиатуре MacBookPro. Брэдли говорит, что это работает только на Yosemite, но я успешно использовал его на Snow Leopard (10.6.8) и Mavericks (10.9.5). Я также проверил это внутри виртуальной машины Kubuntu, и Caps Lock продолжал правильно работать внутри виртуальной машины.

  • Откройте системные настройки клавиатуры и нажмите Modifier Keys...:

введите описание изображения здесь

  • Установите для клавиши Caps Lock значение No Actionи нажмите OK:

                    введите описание изображения здесь

  • Нажмите Modifier Keys...еще раз и установите для клавиши Caps Lock значение Caps Lock, а затем нажмите OK:

                    введите описание изображения здесь

Это остается в силе только до следующей перезагрузки.

На меня это не подействовало. (Sierra 10.12.6, USB-клавиатура Mac и внутренняя часть MBPro)
Диалоги больше не выглядят так, по крайней мере, в Big Sur 11.5.2 на MBP 2019 года. Caps Lock не указан как клавиша-модификатор, поэтому ее нельзя переназначить. Кроме того, я не замечаю задержки, и в отличие от рассматриваемого вопроса :) Я не использую Linux и хотел бы вернуть задержку!
  1. Загрузите и установите следующее программное обеспечение
  • Карабин
  • Хаммерспун
  1. Используйте карабин для сопоставления клавиши CapsLock с F19.
  2. Отредактируйте init.luaпуть ~/.hammerspoon, вставьте код ниже.
pressedF19 = function()
    hs.hid.capslock.toggle()
end

hs.hotkey.bind({}, 'F19', pressedF19, nil)

Затем перезагрузите конфигурацию Hammerspoon, чтобы изменения вступили в силу.

Смотрите мой блог здесь http://hellohtml5.com/2019/04/25/best-way-to-disable-capslock-delay-on-mac/

Привет, добро пожаловать в Ask Different. Спасибо за ваш пост, но обратите внимание, что вопрос касается Linux, ОП уже решил проблему на macOS.
(Оффтоп так как работает на MacOS, а не на Linux) На данный момент достаточно установить только Karabiner, он (начиная с 13.3.0, см. здесь - karabiner-elements.pqrs.org/docs/help/how-to/… ) автоматически отключается Задержка CapsLock без каких-либо ручных действий.

Я написал очень легкий инструмент с открытым исходным кодом, чтобы исправить именно это:

https://github.com/gkpln3/CapsLockNoDelay