void wxMultiColumnListCtrl::OnKey(wxKeyEvent& event) { if (event.GetEventType() == wxEVT_KEY_UP) { if (event.GetKeyCode() == GetModifierKey()) { // The window will close, don't select the item under mouse pointer m_ptMouse.x = m_ptMouse.y = -2; SendCloseEvent(); } event.Skip(); return; } if (event.GetKeyCode() == WXK_ESCAPE || event.GetKeyCode() == WXK_RETURN || event.GetKeyCode() == WXK_NUMPAD_ENTER) { // The window will close, don't select the item under mouse pointer m_ptMouse.x = m_ptMouse.y = -2; if (event.GetKeyCode() == WXK_ESCAPE) m_items.SetSelection(-1); SendCloseEvent(); } else if (event.GetKeyCode() == WXK_TAB || event.GetKeyCode() == GetExtraNavigationKey()) { if (event.ShiftDown()) { m_items.SetSelection(m_items.GetSelection() - 1); if (m_items.GetSelection() < 0) m_items.SetSelection(m_items.GetItemCount() - 1); AdvanceToNextSelectableItem(-1); } else { m_items.SetSelection(m_items.GetSelection() + 1); if (m_items.GetSelection() >= m_items.GetItemCount()) m_items.SetSelection(0); AdvanceToNextSelectableItem(1); } GenerateSelectionEvent(); Refresh(); } else if (event.GetKeyCode() == WXK_DOWN || event.GetKeyCode() == WXK_NUMPAD_DOWN) { m_items.SetSelection(m_items.GetSelection() + 1); if (m_items.GetSelection() >= m_items.GetItemCount()) m_items.SetSelection(0); AdvanceToNextSelectableItem(1); GenerateSelectionEvent(); Refresh(); } else if (event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_NUMPAD_UP) { m_items.SetSelection(m_items.GetSelection() - 1); if (m_items.GetSelection() < 0) m_items.SetSelection(m_items.GetItemCount() - 1); AdvanceToNextSelectableItem(-1); GenerateSelectionEvent(); Refresh(); } else if (event.GetKeyCode() == WXK_HOME || event.GetKeyCode() == WXK_NUMPAD_HOME) { m_items.SetSelection(0); AdvanceToNextSelectableItem(1); GenerateSelectionEvent(); Refresh(); } else if (event.GetKeyCode() == WXK_END || event.GetKeyCode() == WXK_NUMPAD_END) { m_items.SetSelection(m_items.GetItemCount() - 1); AdvanceToNextSelectableItem(-1); GenerateSelectionEvent(); Refresh(); } else if (event.GetKeyCode() == WXK_LEFT || event.GetKeyCode() == WXK_NUMPAD_LEFT) { wxSwitcherItem& item = m_items.GetItem(m_items.GetSelection()); int row = item.GetRowPos(); int newCol = item.GetColPos() - 1; if (newCol < 0) newCol = (m_items.GetColumnCount() - 1); // Find the first item from the end whose row matches and whose column is equal or lower int i; for (i = m_items.GetItemCount()-1; i >= 0; i--) { wxSwitcherItem& item2 = m_items.GetItem(i); if (item2.GetColPos() == newCol && item2.GetRowPos() <= row) { m_items.SetSelection(i); break; } } AdvanceToNextSelectableItem(-1); GenerateSelectionEvent(); Refresh(); } else if (event.GetKeyCode() == WXK_RIGHT || event.GetKeyCode() == WXK_NUMPAD_RIGHT) { wxSwitcherItem& item = m_items.GetItem(m_items.GetSelection()); int row = item.GetRowPos(); int newCol = item.GetColPos() + 1; if (newCol >= m_items.GetColumnCount()) newCol = 0; // Find the first item from the end whose row matches and whose column is equal or lower int i; for (i = m_items.GetItemCount()-1; i >= 0; i--) { wxSwitcherItem& item2 = m_items.GetItem(i); if (item2.GetColPos() == newCol && item2.GetRowPos() <= row) { m_items.SetSelection(i); break; } } AdvanceToNextSelectableItem(1); GenerateSelectionEvent(); Refresh(); } else event.Skip(); }
void KeymapWrapper::InitBySystemSettings() { PR_LOG(gKeymapWrapperLog, PR_LOG_ALWAYS, ("KeymapWrapper(%p): InitBySystemSettings, mGdkKeymap=%p", this, mGdkKeymap)); Display* display = gdk_x11_display_get_xdisplay(gdk_display_get_default()); int min_keycode = 0; int max_keycode = 0; XDisplayKeycodes(display, &min_keycode, &max_keycode); int keysyms_per_keycode = 0; KeySym* xkeymap = XGetKeyboardMapping(display, min_keycode, max_keycode - min_keycode + 1, &keysyms_per_keycode); if (!xkeymap) { PR_LOG(gKeymapWrapperLog, PR_LOG_ALWAYS, ("KeymapWrapper(%p): InitBySystemSettings, " "Failed due to null xkeymap", this)); return; } XModifierKeymap* xmodmap = XGetModifierMapping(display); if (!xmodmap) { PR_LOG(gKeymapWrapperLog, PR_LOG_ALWAYS, ("KeymapWrapper(%p): InitBySystemSettings, " "Failed due to null xmodmap", this)); XFree(xkeymap); return; } PR_LOG(gKeymapWrapperLog, PR_LOG_ALWAYS, ("KeymapWrapper(%p): InitBySystemSettings, min_keycode=%d, " "max_keycode=%d, keysyms_per_keycode=%d, max_keypermod=%d", this, min_keycode, max_keycode, keysyms_per_keycode, xmodmap->max_keypermod)); // The modifiermap member of the XModifierKeymap structure contains 8 sets // of max_keypermod KeyCodes, one for each modifier in the order Shift, // Lock, Control, Mod1, Mod2, Mod3, Mod4, and Mod5. // Only nonzero KeyCodes have meaning in each set, and zero KeyCodes are // ignored. // Note that two or more modifiers may use one modifier flag. E.g., // on Ubuntu 10.10, Alt and Meta share the Mod1 in default settings. // And also Super and Hyper share the Mod4. In such cases, we need to // decide which modifier flag means one of DOM modifiers. // mod[0] is Modifier introduced by Mod1. Modifier mod[5]; int32_t foundLevel[5]; for (uint32_t i = 0; i < ArrayLength(mod); i++) { mod[i] = NOT_MODIFIER; foundLevel[i] = INT32_MAX; } const uint32_t map_size = 8 * xmodmap->max_keypermod; for (uint32_t i = 0; i < map_size; i++) { KeyCode keycode = xmodmap->modifiermap[i]; PR_LOG(gKeymapWrapperLog, PR_LOG_ALWAYS, ("KeymapWrapper(%p): InitBySystemSettings, " " i=%d, keycode=0x%08X", this, i, keycode)); if (!keycode || keycode < min_keycode || keycode > max_keycode) { continue; } ModifierKey* modifierKey = GetModifierKey(keycode); if (!modifierKey) { modifierKey = mModifierKeys.AppendElement(ModifierKey(keycode)); } const KeySym* syms = xkeymap + (keycode - min_keycode) * keysyms_per_keycode; const uint32_t bit = i / xmodmap->max_keypermod; modifierKey->mMask |= 1 << bit; // We need to know the meaning of Mod1, Mod2, Mod3, Mod4 and Mod5. // Let's skip if current map is for others. if (bit < 3) { continue; } const int32_t modIndex = bit - 3; for (int32_t j = 0; j < keysyms_per_keycode; j++) { Modifier modifier = GetModifierForGDKKeyval(syms[j]); PR_LOG(gKeymapWrapperLog, PR_LOG_ALWAYS, ("KeymapWrapper(%p): InitBySystemSettings, " " Mod%d, j=%d, syms[j]=%s(0x%X), modifier=%s", this, modIndex + 1, j, gdk_keyval_name(syms[j]), syms[j], GetModifierName(modifier))); switch (modifier) { case NOT_MODIFIER: // Don't overwrite the stored information with // NOT_MODIFIER. break; case CAPS_LOCK: case SHIFT: case CTRL: // Ignore the modifiers defined in GDK spec. They shouldn't // be mapped to Mod1-5 because they must not work on native // GTK applications. break; default: // If new modifier is found in higher level than stored // value, we don't need to overwrite it. if (j > foundLevel[modIndex]) { break; } // If new modifier is more important than stored value, // we should overwrite it with new modifier. if (j == foundLevel[modIndex]) { mod[modIndex] = std::min(modifier, mod[modIndex]); break; } foundLevel[modIndex] = j; mod[modIndex] = modifier; break; } } } for (uint32_t i = 0; i < COUNT_OF_MODIFIER_INDEX; i++) { Modifier modifier; switch (i) { case INDEX_NUM_LOCK: modifier = NUM_LOCK; break; case INDEX_SCROLL_LOCK: modifier = SCROLL_LOCK; break; case INDEX_ALT: modifier = ALT; break; case INDEX_META: modifier = META; break; case INDEX_SUPER: modifier = SUPER; break; case INDEX_HYPER: modifier = HYPER; break; case INDEX_LEVEL3: modifier = LEVEL3; break; case INDEX_LEVEL5: modifier = LEVEL5; break; default: MOZ_CRASH("All indexes must be handled here"); } for (uint32_t j = 0; j < ArrayLength(mod); j++) { if (modifier == mod[j]) { mModifierMasks[i] |= 1 << (j + 3); } } } XFreeModifiermap(xmodmap); XFree(xkeymap); }