Skip to content

Commit beb0bad

Browse files
committed
Port menu shortcut.
1 parent 77b557a commit beb0bad

File tree

6 files changed

+113
-0
lines changed

6 files changed

+113
-0
lines changed

src/api/menu/menu.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ class Menu : public Base {
8989
virtual void Call(const std::string& method,
9090
const base::ListValue& arguments) OVERRIDE;
9191

92+
#if defined(OS_LINUX)
93+
void UpdateKeys(GtkAccelGroup *gtk_accel_group);
94+
#endif
95+
9296
private:
9397
friend class MenuItem;
9498
friend class Tray;
@@ -101,6 +105,12 @@ class Menu : public Base {
101105
void Remove(MenuItem* menu_item, int pos);
102106
void Popup(int x, int y, content::Shell*);
103107

108+
#if defined(OS_LINUX)
109+
std::vector<MenuItem*> menu_items;
110+
GtkAccelGroup *gtk_accel_group;
111+
#endif
112+
113+
104114
#if defined(OS_MACOSX)
105115
friend class nw::NativeWindowCocoa;
106116
NSMenu* menu_;

src/api/menu/menu_gtk.cc

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include "content/public/browser/web_contents.h"
2828
#include "content/public/browser/render_widget_host_view.h"
2929
#include "ui/gfx/point.h"
30+
#include "vector"
31+
#include "gtk/gtk.h"
3032

3133
namespace nwapi {
3234

@@ -86,6 +88,7 @@ void PointMenuPositionFunc(GtkMenu* menu,
8688
} // namespace
8789

8890
void Menu::Create(const base::DictionaryValue& option) {
91+
gtk_accel_group = NULL;
8992
std::string type;
9093
if (option.GetString("type", &type) && type == "menubar")
9194
menu_ = gtk_menu_bar_new();
@@ -102,14 +105,25 @@ void Menu::Destroy() {
102105
}
103106

104107
void Menu::Append(MenuItem* menu_item) {
108+
menu_items.push_back(menu_item);
109+
if (GTK_IS_ACCEL_GROUP(gtk_accel_group)){
110+
menu_item->UpdateKeys(gtk_accel_group);
111+
}
105112
gtk_menu_shell_append(GTK_MENU_SHELL(menu_), menu_item->menu_item_);
106113
}
107114

108115
void Menu::Insert(MenuItem* menu_item, int pos) {
116+
std::vector<MenuItem*>::iterator begin = menu_items.begin();
117+
menu_items.insert(begin+pos,menu_item);
118+
if (GTK_IS_ACCEL_GROUP(gtk_accel_group)){
119+
menu_item->UpdateKeys(gtk_accel_group);
120+
}
109121
gtk_menu_shell_insert(GTK_MENU_SHELL(menu_), menu_item->menu_item_, pos);
110122
}
111123

112124
void Menu::Remove(MenuItem* menu_item, int pos) {
125+
std::vector<MenuItem*>::iterator begin = menu_items.begin();
126+
menu_items.erase(begin+pos);
113127
gtk_container_remove(GTK_CONTAINER(menu_), menu_item->menu_item_);
114128
}
115129

@@ -131,4 +145,21 @@ void Menu::Popup(int x, int y, content::Shell* shell) {
131145
3, triggering_event_time);
132146
}
133147

148+
void Menu::UpdateKeys(GtkAccelGroup *gtk_accel_group){
149+
this->gtk_accel_group = gtk_accel_group;
150+
if (!GTK_IS_ACCEL_GROUP(gtk_accel_group)){
151+
return ;
152+
} else {
153+
std::vector<MenuItem*>::iterator menu_item_iterator = menu_items.begin();
154+
std::vector<MenuItem*>::iterator menu_item_end = menu_items.end();
155+
while (menu_item_iterator != menu_item_end){
156+
MenuItem *menu_item = *menu_item_iterator;
157+
if (menu_item!=NULL && GTK_IS_MENU_ITEM(menu_item->menu_item_)){
158+
menu_item->UpdateKeys(gtk_accel_group);
159+
}
160+
++menu_item_iterator;
161+
}
162+
}
163+
}
164+
134165
} // namespace nwapi

src/api/menuitem/menuitem.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ class MenuItem : public Base {
5656
virtual void Call(const std::string& method,
5757
const base::ListValue& arguments) OVERRIDE;
5858

59+
#if defined(OS_LINUX)
60+
void UpdateKeys(GtkAccelGroup *gtk_accel_group);
61+
#endif
62+
5963
#if defined(OS_MACOSX) || defined(OS_WIN)
6064
void OnClick();
6165
#endif
@@ -73,6 +77,15 @@ class MenuItem : public Base {
7377
void SetChecked(bool checked);
7478
void SetSubmenu(Menu* sub_menu);
7579

80+
#if defined(OS_LINUX)
81+
GtkAccelGroup *gtk_accel_group;
82+
GdkModifierType modifiers_mask;
83+
guint keyval;
84+
bool enable_shortcut;
85+
Menu* submenu_;
86+
std::string label_;
87+
#endif
88+
7689
#if defined(OS_MACOSX)
7790
std::string type_;
7891

src/api/menuitem/menuitem_gtk.cc

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@
2323
#include "base/values.h"
2424
#include "content/nw/src/api/dispatcher_host.h"
2525
#include "content/nw/src/api/menu/menu.h"
26+
#include "gdk/gdkkeysyms.h"//to get keyval from name
2627

2728
namespace nwapi {
2829

2930
void MenuItem::Create(const base::DictionaryValue& option) {
3031
std::string type;
3132
option.GetString("type", &type);
33+
submenu_ = NULL;
3234

3335
if (type == "separator") {
3436
menu_item_ = gtk_separator_menu_item_new();
@@ -60,6 +62,31 @@ void MenuItem::Create(const base::DictionaryValue& option) {
6062
int menu_id;
6163
if (option.GetInteger("submenu", &menu_id))
6264
SetSubmenu(dispatcher_host()->GetApiObject<Menu>(menu_id));
65+
std::string key;
66+
if (option.GetString("key",&key)){
67+
enable_shortcut = true;
68+
std::string modifiers = "";
69+
option.GetString("modifiers",&modifiers);
70+
modifiers_mask = GdkModifierType(0);
71+
if (modifiers.size() != 0){
72+
if (modifiers.find("ctrl") != std::string::npos){
73+
modifiers_mask = GdkModifierType(modifiers_mask|GDK_CONTROL_MASK);
74+
}
75+
if (modifiers.find("alt") != std::string::npos){
76+
modifiers_mask = GdkModifierType(modifiers_mask|GDK_MOD1_MASK);
77+
}
78+
if (modifiers.find("super") != std::string::npos){
79+
modifiers_mask = GdkModifierType(modifiers_mask|GDK_SUPER_MASK);
80+
}
81+
if (modifiers.find("meta") != std::string::npos){
82+
modifiers_mask = GdkModifierType(modifiers_mask|GDK_META_MASK);
83+
}
84+
}
85+
keyval = gdk_keyval_from_name(key.c_str());
86+
87+
} else {
88+
enable_shortcut = false;
89+
}
6390

6491
block_active_ = false;
6592
g_signal_connect(menu_item_, "activate",
@@ -76,6 +103,7 @@ void MenuItem::Destroy() {
76103
}
77104

78105
void MenuItem::SetLabel(const std::string& label) {
106+
label_ = label;
79107
gtk_menu_item_set_label(GTK_MENU_ITEM(menu_item_), label.c_str());
80108
}
81109

@@ -106,6 +134,10 @@ void MenuItem::SetChecked(bool checked) {
106134
}
107135

108136
void MenuItem::SetSubmenu(Menu* sub_menu) {
137+
submenu_ = sub_menu;
138+
if (GTK_IS_ACCEL_GROUP(gtk_accel_group)){
139+
sub_menu->UpdateKeys(gtk_accel_group);
140+
}
109141
if (sub_menu == NULL)
110142
gtk_menu_item_remove_submenu(GTK_MENU_ITEM(menu_item_));
111143
else
@@ -120,4 +152,24 @@ void MenuItem::OnClick(GtkWidget* widget) {
120152
dispatcher_host()->SendEvent(this, "click", args);
121153
}
122154

155+
156+
void MenuItem::UpdateKeys(GtkAccelGroup *gtk_accel_group){
157+
this->gtk_accel_group = gtk_accel_group;
158+
if (enable_shortcut && GTK_IS_ACCEL_GROUP(gtk_accel_group)){
159+
gtk_widget_add_accelerator(
160+
menu_item_,
161+
"activate",
162+
gtk_accel_group,
163+
keyval,
164+
modifiers_mask,
165+
GTK_ACCEL_VISIBLE);
166+
}
167+
if (submenu_ != NULL){
168+
submenu_->UpdateKeys(gtk_accel_group);
169+
}
170+
return;
171+
}
172+
123173
} // namespace nwapi
174+
175+

src/browser/native_window_gtk.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ NativeWindowGtk::NativeWindowGtk(const base::WeakPtr<content::Shell>& shell,
6060
{
6161
window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
6262

63+
gtk_accel_group = gtk_accel_group_new();
64+
gtk_window_add_accel_group(window_,gtk_accel_group);
65+
6366
vbox_ = gtk_vbox_new(FALSE, 0);
6467
gtk_widget_show(vbox_);
6568
gtk_container_add(GTK_CONTAINER(window_), vbox_);
@@ -308,6 +311,7 @@ bool NativeWindowGtk::IsKiosk() {
308311
}
309312

310313
void NativeWindowGtk::SetMenu(nwapi::Menu* menu) {
314+
menu->UpdateKeys(gtk_accel_group);
311315
gtk_box_pack_start(GTK_BOX(vbox_), menu->menu_, FALSE, FALSE, 0);
312316
gtk_box_reorder_child(GTK_BOX(vbox_), menu->menu_, 0);
313317
}

src/browser/native_window_gtk.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ class NativeWindowGtk : public NativeWindow {
8989
// Set WebKit's style from current theme.
9090
void SetWebKitColorStyle();
9191

92+
//Use to bind shortcut
93+
GtkAccelGroup *gtk_accel_group;
94+
9295
// Create toolbar.
9396
void CreateToolbar();
9497

0 commit comments

Comments
 (0)