Home | History | Annotate | Download | only in gtk
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/ui/gtk/accelerators_gtk.h"
      6 
      7 #include <gdk/gdk.h>
      8 #include <gdk/gdkkeysyms.h>
      9 #include <X11/XF86keysym.h>
     10 
     11 #include "base/memory/singleton.h"
     12 #include "chrome/app/chrome_command_ids.h"
     13 #include "ui/base/accelerators/platform_accelerator_gtk.h"
     14 #include "ui/base/events/event_conversion_gtk.h"
     15 #include "ui/base/keycodes/keyboard_code_conversion_gtk.h"
     16 
     17 namespace {
     18 
     19 // A mostly complete list of chrome's accelerators. When one command has
     20 // multiple shortcuts, the first one in this list is considered "primary",
     21 // meaning that it will be displayed in context menus.
     22 const struct AcceleratorMapping {
     23   guint keyval;
     24   int command_id;
     25   GdkModifierType modifier_type;
     26 } kAcceleratorMap[] = {
     27   // Focus.
     28   { GDK_k, IDC_FOCUS_SEARCH, GDK_CONTROL_MASK },
     29   { GDK_e, IDC_FOCUS_SEARCH, GDK_CONTROL_MASK },
     30   { XF86XK_Search, IDC_FOCUS_SEARCH, GdkModifierType(0) },
     31   { GDK_l, IDC_FOCUS_LOCATION, GDK_CONTROL_MASK },
     32   { GDK_d, IDC_FOCUS_LOCATION, GDK_MOD1_MASK },
     33   { GDK_F6, IDC_FOCUS_LOCATION, GdkModifierType(0) },
     34   { XF86XK_OpenURL, IDC_FOCUS_LOCATION, GdkModifierType(0) },
     35   { XF86XK_Go, IDC_FOCUS_LOCATION, GdkModifierType(0) },
     36 
     37   // Tab/window controls.
     38   { GDK_Page_Down, IDC_SELECT_NEXT_TAB, GDK_CONTROL_MASK },
     39   { GDK_Page_Up, IDC_SELECT_PREVIOUS_TAB, GDK_CONTROL_MASK },
     40   { GDK_Page_Down, IDC_MOVE_TAB_NEXT,
     41     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
     42   { GDK_Page_Up, IDC_MOVE_TAB_PREVIOUS,
     43     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
     44   { GDK_Page_Up, IDC_SELECT_PREVIOUS_TAB, GDK_CONTROL_MASK },
     45   { GDK_w, IDC_CLOSE_TAB, GDK_CONTROL_MASK },
     46   { GDK_t, IDC_RESTORE_TAB,
     47     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
     48   { GDK_t, IDC_NEW_TAB, GDK_CONTROL_MASK },
     49   { GDK_n, IDC_NEW_WINDOW, GDK_CONTROL_MASK },
     50   { GDK_n, IDC_NEW_INCOGNITO_WINDOW,
     51     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
     52   { GDK_w, IDC_CLOSE_WINDOW,
     53     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
     54 
     55   { GDK_1, IDC_SELECT_TAB_0, GDK_CONTROL_MASK },
     56   { GDK_2, IDC_SELECT_TAB_1, GDK_CONTROL_MASK },
     57   { GDK_3, IDC_SELECT_TAB_2, GDK_CONTROL_MASK },
     58   { GDK_4, IDC_SELECT_TAB_3, GDK_CONTROL_MASK },
     59   { GDK_5, IDC_SELECT_TAB_4, GDK_CONTROL_MASK },
     60   { GDK_6, IDC_SELECT_TAB_5, GDK_CONTROL_MASK },
     61   { GDK_7, IDC_SELECT_TAB_6, GDK_CONTROL_MASK },
     62   { GDK_8, IDC_SELECT_TAB_7, GDK_CONTROL_MASK },
     63   { GDK_9, IDC_SELECT_LAST_TAB, GDK_CONTROL_MASK },
     64 
     65   { GDK_1, IDC_SELECT_TAB_0, GDK_MOD1_MASK },
     66   { GDK_2, IDC_SELECT_TAB_1, GDK_MOD1_MASK },
     67   { GDK_3, IDC_SELECT_TAB_2, GDK_MOD1_MASK },
     68   { GDK_4, IDC_SELECT_TAB_3, GDK_MOD1_MASK },
     69   { GDK_5, IDC_SELECT_TAB_4, GDK_MOD1_MASK },
     70   { GDK_6, IDC_SELECT_TAB_5, GDK_MOD1_MASK },
     71   { GDK_7, IDC_SELECT_TAB_6, GDK_MOD1_MASK },
     72   { GDK_8, IDC_SELECT_TAB_7, GDK_MOD1_MASK },
     73   { GDK_9, IDC_SELECT_LAST_TAB, GDK_MOD1_MASK },
     74 
     75   { GDK_KP_1, IDC_SELECT_TAB_0, GDK_CONTROL_MASK },
     76   { GDK_KP_2, IDC_SELECT_TAB_1, GDK_CONTROL_MASK },
     77   { GDK_KP_3, IDC_SELECT_TAB_2, GDK_CONTROL_MASK },
     78   { GDK_KP_4, IDC_SELECT_TAB_3, GDK_CONTROL_MASK },
     79   { GDK_KP_5, IDC_SELECT_TAB_4, GDK_CONTROL_MASK },
     80   { GDK_KP_6, IDC_SELECT_TAB_5, GDK_CONTROL_MASK },
     81   { GDK_KP_7, IDC_SELECT_TAB_6, GDK_CONTROL_MASK },
     82   { GDK_KP_8, IDC_SELECT_TAB_7, GDK_CONTROL_MASK },
     83   { GDK_KP_9, IDC_SELECT_LAST_TAB, GDK_CONTROL_MASK },
     84 
     85   { GDK_KP_1, IDC_SELECT_TAB_0, GDK_MOD1_MASK },
     86   { GDK_KP_2, IDC_SELECT_TAB_1, GDK_MOD1_MASK },
     87   { GDK_KP_3, IDC_SELECT_TAB_2, GDK_MOD1_MASK },
     88   { GDK_KP_4, IDC_SELECT_TAB_3, GDK_MOD1_MASK },
     89   { GDK_KP_5, IDC_SELECT_TAB_4, GDK_MOD1_MASK },
     90   { GDK_KP_6, IDC_SELECT_TAB_5, GDK_MOD1_MASK },
     91   { GDK_KP_7, IDC_SELECT_TAB_6, GDK_MOD1_MASK },
     92   { GDK_KP_8, IDC_SELECT_TAB_7, GDK_MOD1_MASK },
     93   { GDK_KP_9, IDC_SELECT_LAST_TAB, GDK_MOD1_MASK },
     94 
     95   { GDK_F4, IDC_CLOSE_TAB, GDK_CONTROL_MASK },
     96   { GDK_F4, IDC_CLOSE_WINDOW, GDK_MOD1_MASK },
     97 
     98   // Zoom level.
     99   { GDK_KP_Add, IDC_ZOOM_PLUS, GDK_CONTROL_MASK },
    100   { GDK_plus, IDC_ZOOM_PLUS,
    101     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
    102   { GDK_equal, IDC_ZOOM_PLUS, GDK_CONTROL_MASK },
    103   { XF86XK_ZoomIn, IDC_ZOOM_PLUS, GdkModifierType(0) },
    104   { GDK_KP_0, IDC_ZOOM_NORMAL, GDK_CONTROL_MASK },
    105   { GDK_0, IDC_ZOOM_NORMAL, GDK_CONTROL_MASK },
    106   { GDK_KP_Subtract, IDC_ZOOM_MINUS, GDK_CONTROL_MASK },
    107   { GDK_minus, IDC_ZOOM_MINUS, GDK_CONTROL_MASK },
    108   { GDK_underscore, IDC_ZOOM_MINUS,
    109     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
    110   { XF86XK_ZoomOut, IDC_ZOOM_MINUS, GdkModifierType(0) },
    111 
    112   // Find in page.
    113   { GDK_g, IDC_FIND_NEXT, GDK_CONTROL_MASK },
    114   { GDK_F3, IDC_FIND_NEXT, GdkModifierType(0) },
    115   { GDK_g, IDC_FIND_PREVIOUS,
    116     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
    117   { GDK_F3, IDC_FIND_PREVIOUS, GDK_SHIFT_MASK },
    118 
    119   // Navigation / toolbar buttons.
    120   { GDK_Home, IDC_HOME, GDK_MOD1_MASK },
    121   { XF86XK_HomePage, IDC_HOME, GdkModifierType(0) },
    122   { GDK_Escape, IDC_STOP, GdkModifierType(0) },
    123   { XF86XK_Stop, IDC_STOP, GdkModifierType(0) },
    124   { GDK_Left, IDC_BACK, GDK_MOD1_MASK },
    125   { XF86XK_Back, IDC_BACK, GdkModifierType(0) },
    126   { GDK_Right, IDC_FORWARD, GDK_MOD1_MASK },
    127   { XF86XK_Forward, IDC_FORWARD, GdkModifierType(0) },
    128   { GDK_r, IDC_RELOAD, GDK_CONTROL_MASK },
    129   { GDK_r, IDC_RELOAD_IGNORING_CACHE,
    130     GdkModifierType(GDK_CONTROL_MASK|GDK_SHIFT_MASK) },
    131   { GDK_F5, IDC_RELOAD, GdkModifierType(0) },
    132   { GDK_F5, IDC_RELOAD_IGNORING_CACHE, GDK_CONTROL_MASK },
    133   { GDK_F5, IDC_RELOAD_IGNORING_CACHE, GDK_SHIFT_MASK },
    134   { XF86XK_Reload, IDC_RELOAD, GdkModifierType(0) },
    135   { XF86XK_Refresh, IDC_RELOAD, GdkModifierType(0) },
    136 
    137   // Dev tools.
    138   { GDK_u, IDC_VIEW_SOURCE, GDK_CONTROL_MASK },
    139   { GDK_i, IDC_DEV_TOOLS,
    140     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
    141   { GDK_F12, IDC_DEV_TOOLS_TOGGLE, GdkModifierType(0) },
    142   { GDK_j, IDC_DEV_TOOLS_CONSOLE,
    143     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
    144   { GDK_c, IDC_DEV_TOOLS_INSPECT,
    145     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
    146   { GDK_Escape, IDC_TASK_MANAGER, GDK_SHIFT_MASK },
    147 
    148   // Editing.
    149   { GDK_c, IDC_COPY, GDK_CONTROL_MASK },
    150   { GDK_x, IDC_CUT, GDK_CONTROL_MASK },
    151   { GDK_v, IDC_PASTE, GDK_CONTROL_MASK },
    152 
    153   // Miscellany.
    154   { GDK_d, IDC_BOOKMARK_ALL_TABS,
    155     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
    156   { GDK_d, IDC_BOOKMARK_PAGE, GDK_CONTROL_MASK },
    157   { GDK_o, IDC_OPEN_FILE, GDK_CONTROL_MASK },
    158   { GDK_f, IDC_FIND, GDK_CONTROL_MASK },
    159   { GDK_p, IDC_PRINT, GDK_CONTROL_MASK },
    160   { GDK_p, IDC_ADVANCED_PRINT,
    161     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
    162   { GDK_b, IDC_SHOW_BOOKMARK_BAR,
    163     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
    164   { GDK_o, IDC_SHOW_BOOKMARK_MANAGER,
    165     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
    166   { GDK_F11, IDC_FULLSCREEN, GdkModifierType(0) },
    167   { GDK_Delete, IDC_CLEAR_BROWSING_DATA,
    168     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
    169   { GDK_h, IDC_SHOW_HISTORY, GDK_CONTROL_MASK },
    170   { GDK_j, IDC_SHOW_DOWNLOADS, GDK_CONTROL_MASK },
    171   { GDK_F1, IDC_HELP_PAGE_VIA_KEYBOARD, GdkModifierType(0) },
    172   { XF86XK_AddFavorite, IDC_BOOKMARK_PAGE, GdkModifierType(0) },
    173   { XF86XK_Favorites, IDC_SHOW_BOOKMARK_BAR, GdkModifierType(0) },
    174   { XF86XK_History, IDC_SHOW_HISTORY, GdkModifierType(0) },
    175   { GDK_q, IDC_EXIT, GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
    176   { GDK_s, IDC_SAVE_PAGE, GDK_CONTROL_MASK },
    177   { GDK_e, IDC_SHOW_APP_MENU, GDK_MOD1_MASK },
    178   { GDK_f, IDC_SHOW_APP_MENU, GDK_MOD1_MASK },
    179   { GDK_m, IDC_SHOW_AVATAR_MENU,
    180     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK)},
    181   { GDK_greater, IDC_TOGGLE_SPEECH_INPUT,
    182     GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) },
    183 };
    184 
    185 }  // namespace
    186 
    187 // static
    188 AcceleratorsGtk* AcceleratorsGtk::GetInstance() {
    189   return Singleton<AcceleratorsGtk>::get();
    190 }
    191 
    192 const ui::Accelerator* AcceleratorsGtk::GetPrimaryAcceleratorForCommand(
    193     int command_id) {
    194   AcceleratorMap::const_iterator i(primary_accelerators_.find(command_id));
    195   return i != primary_accelerators_.end() ? &i->second : NULL;
    196 }
    197 
    198 AcceleratorsGtk::AcceleratorsGtk() {
    199   for (size_t i = 0; i < arraysize(kAcceleratorMap); ++i) {
    200     const AcceleratorMapping& entry = kAcceleratorMap[i];
    201 
    202     ui::Accelerator accelerator = ui::AcceleratorForGdkKeyCodeAndModifier(
    203         entry.keyval, entry.modifier_type);
    204 
    205     all_accelerators_.push_back(std::make_pair(entry.command_id, accelerator));
    206     if (primary_accelerators_.find(entry.command_id) ==
    207         primary_accelerators_.end()) {
    208       primary_accelerators_[entry.command_id] = accelerator;
    209     }
    210   }
    211 }
    212 
    213 AcceleratorsGtk::~AcceleratorsGtk() {}
    214