gtk: Enabling setting menubar for window.

This commit is contained in:
Cheng Zhao 2014-03-14 21:44:09 +08:00
parent 4e4e0f5d4d
commit 23ebfa2955
5 changed files with 41 additions and 4 deletions

View file

@ -4,11 +4,14 @@
#include "browser/api/atom_api_menu_gtk.h" #include "browser/api/atom_api_menu_gtk.h"
#include "browser/native_window.h" #include "browser/native_window_gtk.h"
#include "common/v8/native_type_conversions.h"
#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/render_widget_host_view.h"
#include "ui/gfx/point.h" #include "ui/gfx/point.h"
#include "ui/gfx/screen.h" #include "ui/gfx/screen.h"
#include "common/v8/node_common.h"
namespace atom { namespace atom {
namespace api { namespace api {
@ -40,6 +43,15 @@ void MenuGtk::Popup(NativeWindow* native_window) {
// static // static
void Menu::AttachToWindow(const v8::FunctionCallbackInfo<v8::Value>& args) { void Menu::AttachToWindow(const v8::FunctionCallbackInfo<v8::Value>& args) {
Menu* self = ObjectWrap::Unwrap<Menu>(args.This());
if (self == NULL)
return node::ThrowError("Menu is already destroyed");
NativeWindow* native_window;
if (!FromV8Arguments(args, &native_window))
return node::ThrowTypeError("Bad argument");
static_cast<NativeWindowGtk*>(native_window)->SetMenu(self->model_.get());
} }
// static // static

View file

@ -31,9 +31,11 @@ NativeWindowGtk::NativeWindowGtk(content::WebContents* web_contents,
base::DictionaryValue* options) base::DictionaryValue* options)
: NativeWindow(web_contents, options), : NativeWindow(web_contents, options),
window_(GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL))), window_(GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL))),
vbox_(gtk_vbox_new(FALSE, 0)),
state_(GDK_WINDOW_STATE_WITHDRAWN), state_(GDK_WINDOW_STATE_WITHDRAWN),
is_always_on_top_(false) { is_always_on_top_(false) {
gtk_container_add(GTK_CONTAINER(window_), gtk_container_add(GTK_CONTAINER(window_), vbox_);
gtk_container_add(GTK_CONTAINER(vbox_),
GetWebContents()->GetView()->GetNativeView()); GetWebContents()->GetView()->GetNativeView());
int width = 800, height = 600; int width = 800, height = 600;
@ -254,6 +256,12 @@ gfx::NativeWindow NativeWindowGtk::GetNativeWindow() {
return window_; return window_;
} }
void NativeWindowGtk::SetMenu(ui::MenuModel* menu_model) {
menu_.reset(new ::MenuGtk(this, menu_model, true));
gtk_box_pack_start(GTK_BOX(vbox_), menu_->widget(), FALSE, FALSE, 0);
gtk_box_reorder_child(GTK_BOX(vbox_), menu_->widget(), 0);
}
void NativeWindowGtk::UpdateDraggableRegions( void NativeWindowGtk::UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) { const std::vector<DraggableRegion>& regions) {
// Draggable region is not supported for non-frameless window. // Draggable region is not supported for non-frameless window.

View file

@ -8,13 +8,15 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "browser/native_window.h" #include "browser/native_window.h"
#include "browser/ui/gtk/menu_gtk.h"
#include "third_party/skia/include/core/SkRegion.h" #include "third_party/skia/include/core/SkRegion.h"
#include "ui/base/gtk/gtk_signal.h" #include "ui/base/gtk/gtk_signal.h"
#include "ui/gfx/size.h" #include "ui/gfx/size.h"
namespace atom { namespace atom {
class NativeWindowGtk : public NativeWindow { class NativeWindowGtk : public NativeWindow,
public MenuGtk::Delegate {
public: public:
explicit NativeWindowGtk(content::WebContents* web_contents, explicit NativeWindowGtk(content::WebContents* web_contents,
base::DictionaryValue* options); base::DictionaryValue* options);
@ -56,6 +58,9 @@ class NativeWindowGtk : public NativeWindow {
virtual bool HasModalDialog() OVERRIDE; virtual bool HasModalDialog() OVERRIDE;
virtual gfx::NativeWindow GetNativeWindow() OVERRIDE; virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
// Set the native window menu.
void SetMenu(ui::MenuModel* menu_model);
protected: protected:
virtual void UpdateDraggableRegions( virtual void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) OVERRIDE; const std::vector<DraggableRegion>& regions) OVERRIDE;
@ -83,6 +88,7 @@ class NativeWindowGtk : public NativeWindow {
GdkEventButton*); GdkEventButton*);
GtkWindow* window_; GtkWindow* window_;
GtkWidget* vbox_;
GdkWindowState state_; GdkWindowState state_;
bool is_always_on_top_; bool is_always_on_top_;
@ -101,6 +107,9 @@ class NativeWindowGtk : public NativeWindow {
// custom frame border. We set it to NULL if we want the default cursor. // custom frame border. We set it to NULL if we want the default cursor.
GdkCursor* frame_cursor_; GdkCursor* frame_cursor_;
// The window menu.
scoped_ptr<MenuGtk> menu_;
DISALLOW_COPY_AND_ASSIGN(NativeWindowGtk); DISALLOW_COPY_AND_ASSIGN(NativeWindowGtk);
}; };

View file

@ -182,6 +182,7 @@ MenuGtk::MenuGtk(MenuGtk::Delegate* delegate,
bool is_menubar) bool is_menubar)
: delegate_(delegate), : delegate_(delegate),
model_(model), model_(model),
is_menubar_(is_menubar),
dummy_accel_group_(gtk_accel_group_new()), dummy_accel_group_(gtk_accel_group_new()),
menu_(is_menubar ? gtk_menu_bar_new() : gtk_custom_menu_new()), menu_(is_menubar ? gtk_menu_bar_new() : gtk_custom_menu_new()),
weak_factory_(this) { weak_factory_(this) {
@ -331,7 +332,8 @@ void MenuGtk::PopupAsFromKeyEvent(GtkWidget* widget) {
} }
void MenuGtk::Cancel() { void MenuGtk::Cancel() {
gtk_menu_popdown(GTK_MENU(menu_)); if (!is_menubar_)
gtk_menu_popdown(GTK_MENU(menu_));
} }
void MenuGtk::UpdateMenu() { void MenuGtk::UpdateMenu() {
@ -710,6 +712,9 @@ void MenuGtk::OnSubMenuShow(GtkWidget* submenu) {
} }
void MenuGtk::OnSubMenuHidden(GtkWidget* submenu) { void MenuGtk::OnSubMenuHidden(GtkWidget* submenu) {
if (is_menubar_)
return;
// Increase the reference count of the old submenu, and schedule it to be // Increase the reference count of the old submenu, and schedule it to be
// deleted later. We get this hide notification before we've processed menu // deleted later. We get this hide notification before we've processed menu
// activations, so if we were to delete the submenu now, we might lose the // activations, so if we were to delete the submenu now, we might lose the

View file

@ -198,6 +198,9 @@ class MenuGtk {
// menu (overriding the delegate as a controller). // menu (overriding the delegate as a controller).
ui::MenuModel* model_; ui::MenuModel* model_;
// Whether this is a menu bar.
bool is_menubar_;
// For some menu items, we want to show the accelerator, but not actually // For some menu items, we want to show the accelerator, but not actually
// explicitly handle it. To this end we connect those menu items' accelerators // explicitly handle it. To this end we connect those menu items' accelerators
// to this group, but don't attach this group to any top level window. // to this group, but don't attach this group to any top level window.