Commit message: None
CVE: None
Vulnerability description: None

Project: Chrome

void BrowserTitlebar::ActiveWindowChanged(GdkWindow* active_window) {
  if (!window_)
    return;

  window_has_focus_ = GTK_WIDGET(window_)->window == active_window;
  UpdateTextColor();
}

Project: Chrome

BrowserTitlebar::BrowserTitlebar(BrowserWindowGtk* browser_window,
                                 GtkWindow* window)
    : browser_window_(browser_window), window_(window),
      app_mode_favicon_(NULL),
      app_mode_title_(NULL),
      using_custom_frame_(false),
      window_has_focus_(false),
      theme_provider_(NULL) {
  Init();
}

Project: Chrome

CustomDrawButton* BrowserTitlebar::BuildTitlebarButton(int image,
    int image_pressed, int image_hot, GtkWidget* box, int tooltip) {
  CustomDrawButton* button = new CustomDrawButton(image, image_pressed,
                                                  image_hot, 0);
  gtk_widget_add_events(GTK_WIDGET(button->widget()), GDK_POINTER_MOTION_MASK);
  g_signal_connect(button->widget(), "clicked", G_CALLBACK(OnButtonClicked),
                   this);
  g_signal_connect(button->widget(), "motion-notify-event",
                   G_CALLBACK(OnMouseMoveEvent), browser_window_);
  std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip);
  gtk_widget_set_tooltip_text(button->widget(),
                              localized_tooltip.c_str());
  gtk_box_pack_end(GTK_BOX(box), button->widget(), FALSE, FALSE, 0);
  return button;
}

Project: Chrome

void BrowserTitlebar::ExecuteCommand(int command_id) {
  if (command_id == kShowWindowDecorationsCommand) {
    PrefService* prefs = browser_window_->browser()->profile()->GetPrefs();
    prefs->SetBoolean(prefs::kUseCustomChromeFrame,
                  !prefs->GetBoolean(prefs::kUseCustomChromeFrame));
    return;
  }

  browser_window_->browser()->ExecuteCommand(command_id);
}

Project: Chrome

color_utils::HSL GdkColorToHSL(const GdkColor* color) {
  color_utils::HSL hsl;
  color_utils::SkColorToHSL(SkColorSetRGB(color->red >> 8,
                                          color->green >> 8,
                                          color->blue >> 8), &hsl);
  return hsl;
}

Project: Chrome

const MenuCreateMaterial* GetFaviconMenu(Profile* profile,
                                         MenuGtk::Delegate* delegate) {
  static bool favicon_menu_built = false;
  static MenuCreateMaterial* favicon_menu;
  if (!favicon_menu_built) {
    const MenuCreateMaterial* standard_page =
        GetStandardPageMenu(profile, delegate);
    int standard_page_menu_length = 1;
    int start_offset = 0;
    for (int i = 0; standard_page[i].type != MENU_END; ++i) {
      if (standard_page[i].id == IDC_CREATE_SHORTCUTS) {
        start_offset = i + 2;
        ++i;
        continue;
      } else if (start_offset == 0) {
        NOTREACHED();
        continue;
      }

      standard_page_menu_length++;
    }
    favicon_menu = new MenuCreateMaterial[arraysize(g_favicon_menu) +
                                          standard_page_menu_length];
    memcpy(favicon_menu, g_favicon_menu,
           arraysize(g_favicon_menu) * sizeof(MenuCreateMaterial));
    memcpy(favicon_menu + arraysize(g_favicon_menu),
           standard_page + start_offset,
           (standard_page_menu_length) * sizeof(MenuCreateMaterial));
  }
  return favicon_menu;
}

Project: Chrome

GdkPixbuf* BrowserTitlebar::Throbber::GetNextFrame(bool is_waiting) {
  Throbber::InitFrames();
  if (is_waiting) {
    return (*g_throbber_waiting_frames)[current_waiting_frame_++ %
        g_throbber_waiting_frames->size()];
  } else {
    return (*g_throbber_frames)[current_frame_++ % g_throbber_frames->size()];
  }
}

Project: Chrome

GdkPixbuf* GetOTRAvatar() {
  static GdkPixbuf* otr_avatar = NULL;
  if (!otr_avatar) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    otr_avatar = rb.GetRTLEnabledPixbufNamed(IDR_OTR_ICON);
  }
  return otr_avatar;
}

Project: Chrome

void BrowserTitlebar::Init() {
  GtkWidget* container_hbox = gtk_hbox_new(FALSE, 0);

  container_ = gtk_event_box_new();
  gtk_widget_set_name(container_, "chrome-browser-titlebar");
  gtk_event_box_set_visible_window(GTK_EVENT_BOX(container_), FALSE);
  gtk_container_add(GTK_CONTAINER(container_), container_hbox);

  g_signal_connect(G_OBJECT(container_), "scroll-event",
                   G_CALLBACK(OnScroll), this);

  g_signal_connect(window_, "window-state-event",
                   G_CALLBACK(OnWindowStateChanged), this);

  if (browser_window_->browser()->profile()->IsOffTheRecord() &&
      browser_window_->browser()->type() == Browser::TYPE_NORMAL) {
    GtkWidget* spy_guy = gtk_image_new_from_pixbuf(GetOTRAvatar());
    gtk_misc_set_alignment(GTK_MISC(spy_guy), 0.0, 1.0);
    GtkWidget* spy_frame = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
    gtk_alignment_set_padding(GTK_ALIGNMENT(spy_frame), kOTRMaximizedTopSpacing,
        kOTRBottomSpacing, kOTRSideSpacing, kOTRSideSpacing);
    gtk_widget_set_size_request(spy_guy, -1, 0);
    gtk_container_add(GTK_CONTAINER(spy_frame), spy_guy);
    gtk_box_pack_start(GTK_BOX(container_hbox), spy_frame, FALSE, FALSE, 0);
  }

  titlebar_alignment_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
  if (browser_window_->browser()->type() == Browser::TYPE_NORMAL) {
    gtk_box_pack_start(GTK_BOX(container_hbox), titlebar_alignment_, TRUE,
                       TRUE, 0);

    gtk_container_add(GTK_CONTAINER(titlebar_alignment_),
                      browser_window_->tabstrip()->widget());
  } else {
    gtk_box_pack_start(GTK_BOX(container_hbox), titlebar_alignment_, TRUE,
                       TRUE, 0);
    GtkWidget* app_mode_hbox = gtk_hbox_new(FALSE, kIconTitleSpacing);
    gtk_container_add(GTK_CONTAINER(titlebar_alignment_), app_mode_hbox);

    gtk_box_pack_start(GTK_BOX(app_mode_hbox),
        browser_window_->tabstrip()->widget(), FALSE, FALSE, 0);

    GtkWidget* favicon_event_box = gtk_event_box_new();
    gtk_event_box_set_visible_window(GTK_EVENT_BOX(favicon_event_box), FALSE);
    g_signal_connect(favicon_event_box, "button-press-event",
                     G_CALLBACK(OnButtonPressed), this);
    gtk_box_pack_start(GTK_BOX(app_mode_hbox), favicon_event_box, FALSE,
                       FALSE, 0);
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    app_mode_favicon_ = gtk_image_new_from_pixbuf(
        rb.GetRTLEnabledPixbufNamed(IDR_PRODUCT_LOGO_16));
    g_object_set_data(G_OBJECT(app_mode_favicon_), "left-align-popup",
                      reinterpret_cast<void*>(true));
    gtk_container_add(GTK_CONTAINER(favicon_event_box), app_mode_favicon_);

    app_mode_title_ = gtk_label_new(NULL);
    gtk_label_set_ellipsize(GTK_LABEL(app_mode_title_), PANGO_ELLIPSIZE_END);
    gtk_misc_set_alignment(GTK_MISC(app_mode_title_), 0.0, 0.5);
    gtk_box_pack_start(GTK_BOX(app_mode_hbox), app_mode_title_, TRUE, TRUE,
                       0);

    theme_provider_ = GtkThemeProvider::GetFrom(
        browser_window_->browser()->profile());
    registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
                   NotificationService::AllSources());
    theme_provider_->InitThemesFor(this);
    UpdateTitleAndIcon();
  }

  titlebar_buttons_box_ = gtk_vbox_new(FALSE, 0);
  GtkWidget* buttons_hbox = gtk_hbox_new(FALSE, kButtonSpacing);
  top_padding_ = gtk_fixed_new();
  gtk_widget_set_size_request(top_padding_, -1, kButtonOuterPadding);
  gtk_box_pack_start(GTK_BOX(titlebar_buttons_box_), top_padding_, FALSE, FALSE,
                     0);
  gtk_box_pack_start(GTK_BOX(titlebar_buttons_box_), buttons_hbox, FALSE,
                     FALSE, 0);

  if (CommandLine::ForCurrentProcess()->HasSwitch("glen")) {
    close_button_.reset(BuildTitlebarButton(IDR_GLEN, IDR_GLEN, IDR_GLEN,
                                            buttons_hbox, IDS_GLEN));
  } else {
    close_button_.reset(BuildTitlebarButton(IDR_CLOSE, IDR_CLOSE_P, IDR_CLOSE_H,
                                            buttons_hbox,
                                            IDS_XPFRAME_CLOSE_TOOLTIP));
  }

  restore_button_.reset(BuildTitlebarButton(IDR_RESTORE, IDR_RESTORE_P,
                        IDR_RESTORE_H, buttons_hbox,
                        IDS_XPFRAME_RESTORE_TOOLTIP));
  maximize_button_.reset(BuildTitlebarButton(IDR_MAXIMIZE, IDR_MAXIMIZE_P,
                         IDR_MAXIMIZE_H, buttons_hbox,
                         IDS_XPFRAME_MAXIMIZE_TOOLTIP));
  minimize_button_.reset(BuildTitlebarButton(IDR_MINIMIZE, IDR_MINIMIZE_P,
                         IDR_MINIMIZE_H, buttons_hbox,
                         IDS_XPFRAME_MINIMIZE_TOOLTIP));

  gtk_widget_size_request(close_button_->widget(), &close_button_req_);
  gtk_widget_size_request(minimize_button_->widget(), &minimize_button_req_);
  gtk_widget_size_request(restore_button_->widget(), &restore_button_req_);

  gtk_box_pack_end(GTK_BOX(container_hbox), titlebar_buttons_box_, FALSE,
                   FALSE, 0);

  gtk_widget_show_all(container_);

  ActiveWindowWatcherX::AddObserver(this);
}

Project: Chrome

void BrowserTitlebar::Throbber::InitFrames() {
  if (g_throbber_frames)
    return;

  g_throbber_frames = new std::vector<GdkPixbuf*>;
  MakeThrobberFrames(IDR_THROBBER_LIGHT, g_throbber_frames);

  g_throbber_waiting_frames = new std::vector<GdkPixbuf*>;
  MakeThrobberFrames(IDR_THROBBER_WAITING_LIGHT, g_throbber_waiting_frames);
}

Project: Chrome

bool BrowserTitlebar::IsCommandEnabled(int command_id) const {
  if (command_id == kShowWindowDecorationsCommand)
    return true;

  return browser_window_->browser()->command_updater()->
      IsCommandEnabled(command_id);
}

Project: Chrome

bool BrowserTitlebar::IsItemChecked(int command_id) const {
  if (command_id == kShowWindowDecorationsCommand) {
    PrefService* prefs = browser_window_->browser()->profile()->GetPrefs();
    return !prefs->GetBoolean(prefs::kUseCustomChromeFrame);
  }

  EncodingMenuController controller;
  if (controller.DoesCommandBelongToEncodingMenu(command_id)) {
    TabContents* tab_contents =
        browser_window_->browser()->GetSelectedTabContents();
    if (tab_contents) {
      return controller.IsItemChecked(browser_window_->browser()->profile(),
                                      tab_contents->encoding(),
                                      command_id);
    }
    return false;
  }

  NOTREACHED();
  return false;
}

Project: Chrome

static void MakeThrobberFrames(int resource_id,
                               std::vector<GdkPixbuf*>* frames) {
  ResourceBundle &rb = ResourceBundle::GetSharedInstance();
  SkBitmap* frame_strip = rb.GetBitmapNamed(resource_id);

  int frame_size = frame_strip->height();
  size_t num_frames = frame_strip->width() / frame_size;

  for (size_t i = 0; i < num_frames; ++i) {
    SkBitmap frame = SkBitmapOperations::CreateTiledBitmap(*frame_strip,
        i * frame_size, 0, frame_size, frame_size);
    frames->push_back(gfx::GdkPixbufFromSkBitmap(&frame));
  }
}

Project: Chrome

void BrowserTitlebar::Observe(NotificationType type,
                              const NotificationSource& source,
                              const NotificationDetails& details) {
  switch (type.value) {
    case NotificationType::BROWSER_THEME_CHANGED:
      UpdateTextColor();
      break;

    default:
      NOTREACHED();
  }
}

Project: Chrome

void BrowserTitlebar::OnButtonClicked(GtkWidget* button,
                                      BrowserTitlebar* titlebar) {
  if (titlebar->close_button_->widget() == button) {
    titlebar->browser_window_->Close();
  } else if (titlebar->restore_button_->widget() == button) {
    titlebar->browser_window_->UnMaximize();
  } else if (titlebar->maximize_button_->widget() == button) {
    gtk_window_maximize(titlebar->window_);
  } else if (titlebar->minimize_button_->widget() == button) {
    gtk_window_iconify(titlebar->window_);
  }
}

Project: Chrome

gboolean BrowserTitlebar::OnButtonPressed(GtkWidget* widget,
                                          GdkEventButton* event,
                                          BrowserTitlebar* titlebar) {
  if (event->button != 1)
    return FALSE;

  titlebar->ShowFaviconMenu(event);
  return TRUE;
}

Project: Chrome

gboolean OnMouseMoveEvent(GtkWidget* widget, GdkEventMotion* event,
                          BrowserWindowGtk* browser_window) {
  browser_window->ResetCustomFrameCursor();
  return TRUE;
}

Project: Chrome

gboolean BrowserTitlebar::OnWindowStateChanged(GtkWindow* window,
    GdkEventWindowState* event, BrowserTitlebar* titlebar) {
  if (titlebar->browser_window_->IsMaximized()) {
    gtk_widget_hide(titlebar->maximize_button_->widget());
    gtk_widget_show(titlebar->restore_button_->widget());
  } else {
    gtk_widget_hide(titlebar->restore_button_->widget());
    gtk_widget_show(titlebar->maximize_button_->widget());
  }
  titlebar->UpdateTitlebarAlignment();
  titlebar->UpdateTextColor();
  return FALSE;
}

Project: Chrome

GdkColor PickLuminosityContrastingColor(const GdkColor* base,
                                        const GdkColor* one,
                                        const GdkColor* two) {
  color_utils::HSL baseHSL = GdkColorToHSL(base);
  color_utils::HSL oneHSL = GdkColorToHSL(one);
  color_utils::HSL twoHSL = GdkColorToHSL(two);
  double one_difference = fabs(baseHSL.l - oneHSL.l);
  double two_difference = fabs(baseHSL.l - twoHSL.l);

  if (two_difference > one_difference + 0.1)
    return *two;
  else
    return *one;
}

Project: Chrome

void BrowserTitlebar::Throbber::Reset() {
  current_frame_ = 0;
  current_waiting_frame_ = 0;
}

Project: Chrome

void BrowserTitlebar::ShowContextMenu() {
  if (!context_menu_.get()) {
    static const MenuCreateMaterial context_menu_blueprint[] = {
        { MENU_NORMAL, IDC_NEW_TAB, IDS_TAB_CXMENU_NEWTAB, 0, NULL,
            GDK_t, GDK_CONTROL_MASK, true },
        { MENU_NORMAL, IDC_RESTORE_TAB, IDS_RESTORE_TAB, 0, NULL,
            GDK_t, GDK_CONTROL_MASK | GDK_SHIFT_MASK, true },
        { MENU_SEPARATOR },
        { MENU_NORMAL, IDC_TASK_MANAGER, IDS_TASK_MANAGER, 0, NULL,
            GDK_Escape, GDK_SHIFT_MASK, true },
#if !defined(OS_CHROMEOS)
        { MENU_SEPARATOR },
        { MENU_CHECKBOX, kShowWindowDecorationsCommand,
            IDS_SHOW_WINDOW_DECORATIONS_MENU },
#endif
        { MENU_END },
    };

    context_menu_.reset(new MenuGtk(this, context_menu_blueprint, NULL));
  }

  context_menu_->PopupAsContext(gtk_get_current_event_time());
}

Project: Chrome

void BrowserTitlebar::ShowFaviconMenu(GdkEventButton* event) {
  if (!favicon_menu_.get()) {
    favicon_menu_.reset(new MenuGtk(this,
        GetFaviconMenu(browser_window_->browser()->profile(), this), NULL));
  }

  favicon_menu_->Popup(app_mode_favicon_, reinterpret_cast<GdkEvent*>(event));
}

Project: Chrome

void BrowserTitlebar::UpdateCustomFrame(bool use_custom_frame) {
  using_custom_frame_ = use_custom_frame;
  if (use_custom_frame)
    gtk_widget_show(titlebar_buttons_box_);
  else
    gtk_widget_hide(titlebar_buttons_box_);
  UpdateTitlebarAlignment();
}

Project: Chrome

void BrowserTitlebar::UpdateTextColor() {
  if (app_mode_title_) {
    if (theme_provider_ && theme_provider_->UseGtkTheme()) {
      GdkColor frame_color;
      if (window_has_focus_) {
        frame_color = theme_provider_->GetGdkColor(
          BrowserThemeProvider::COLOR_FRAME);
      } else {
        frame_color = theme_provider_->GetGdkColor(
          BrowserThemeProvider::COLOR_FRAME_INACTIVE);
      }
      GdkColor text_color = PickLuminosityContrastingColor(
          &frame_color, &gfx::kGdkWhite, &gfx::kGdkBlack);
      gtk_util::SetLabelColor(app_mode_title_, &text_color);
    } else {
      gtk_util::SetLabelColor(app_mode_title_, &gfx::kGdkWhite);
    }
  }
}

Project: Chrome

void BrowserTitlebar::UpdateThrobber(TabContents* tab_contents) {
  DCHECK(app_mode_favicon_);

  if (tab_contents && tab_contents->is_loading()) {
    GdkPixbuf* icon_pixbuf =
        throbber_.GetNextFrame(tab_contents->waiting_for_response());
    gtk_image_set_from_pixbuf(GTK_IMAGE(app_mode_favicon_), icon_pixbuf);
  } else {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    if (browser_window_->browser()->type() == Browser::TYPE_APP) {
      SkBitmap icon = browser_window_->browser()->GetCurrentPageIcon();
      if (icon.empty()) {
        gtk_image_set_from_pixbuf(GTK_IMAGE(app_mode_favicon_),
            rb.GetPixbufNamed(IDR_PRODUCT_LOGO_16));
      } else {
        GdkPixbuf* icon_pixbuf = gfx::GdkPixbufFromSkBitmap(&icon);
        gtk_image_set_from_pixbuf(GTK_IMAGE(app_mode_favicon_), icon_pixbuf);
        g_object_unref(icon_pixbuf);
      }
    } else {
      gtk_image_set_from_pixbuf(GTK_IMAGE(app_mode_favicon_),
          rb.GetPixbufNamed(IDR_PRODUCT_LOGO_16));
    }
    throbber_.Reset();
  }
}

Project: Chrome

void BrowserTitlebar::UpdateTitleAndIcon() {
  if (!app_mode_title_)
    return;

  string16 title = browser_window_->browser()->GetWindowTitleForCurrentTab();
  gtk_label_set_text(GTK_LABEL(app_mode_title_), UTF16ToUTF8(title).c_str());

  if (browser_window_->browser()->type() == Browser::TYPE_APP) {
    SkBitmap icon = browser_window_->browser()->GetCurrentPageIcon();
    if (icon.empty()) {
      gtk_util::SetWindowIcon(window_);
    } else {
      GdkPixbuf* icon_pixbuf = gfx::GdkPixbufFromSkBitmap(&icon);
      gtk_window_set_icon(window_, icon_pixbuf);
      g_object_unref(icon_pixbuf);
    }
  }
}

Project: Chrome

void BrowserTitlebar::UpdateTitlebarAlignment() {
  if (browser_window_->browser()->type() == Browser::TYPE_NORMAL) {
    if (using_custom_frame_ && !browser_window_->IsMaximized()) {
      gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_alignment_),
          kTitlebarHeight, 0, kTabStripLeftPadding, 0);
    } else {
      gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_alignment_), 0, 0,
                                kTabStripLeftPadding, 0);
    }
  } else {
    if (using_custom_frame_ && !browser_window_->IsFullscreen()) {
      gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_alignment_),
          kAppModePaddingTop, kAppModePaddingBottom, kAppModePaddingLeft, 0);
      gtk_widget_show(titlebar_alignment_);
    } else {
      gtk_widget_hide(titlebar_alignment_);
    }
  }

  GtkRequisition close_button_req = close_button_req_;
  GtkRequisition minimize_button_req = minimize_button_req_;
  GtkRequisition restore_button_req = restore_button_req_;
  if (using_custom_frame_ && browser_window_->IsMaximized()) {
    close_button_req.width += kButtonOuterPadding;
    close_button_req.height += kButtonOuterPadding;
    minimize_button_req.height += kButtonOuterPadding;
    restore_button_req.height += kButtonOuterPadding;
    gtk_widget_hide(top_padding_);
  } else {
    gtk_widget_show(top_padding_);
  }
  gtk_widget_set_size_request(close_button_->widget(),
                              close_button_req.width, close_button_req.height);
  gtk_widget_set_size_request(minimize_button_->widget(),
                              minimize_button_req.width,
                              minimize_button_req.height);
  gtk_widget_set_size_request(restore_button_->widget(),
                              restore_button_req.width,
                              restore_button_req.height);
}

Project: Chrome

BrowserTitlebar::~BrowserTitlebar() {
  ActiveWindowWatcherX::RemoveObserver(this);
}

Project: Chrome

void MenuGtk::AppendCheckMenuItemWithLabel(int command_id,
                                           const std::string& label) {
  std::string converted_label = ConvertAcceleratorsFromWindowsStyle(label);
  GtkWidget* menu_item =
      gtk_check_menu_item_new_with_mnemonic(converted_label.c_str());
  AppendMenuItem(command_id, menu_item);
}

Project: Chrome

void MenuGtk::AppendMenuItem(int command_id, GtkWidget* menu_item) {
  g_object_set_data(G_OBJECT(menu_item), "menu-id",
                    reinterpret_cast<void*>(command_id));

  g_signal_connect(G_OBJECT(menu_item), "activate",
                   G_CALLBACK(OnMenuItemActivated), this);

  gtk_widget_show(menu_item);
  gtk_menu_shell_append(GTK_MENU_SHELL(menu_.get()), menu_item);
}

Project: Chrome

void MenuGtk::AppendSeparator() {
  GtkWidget* menu_item = gtk_separator_menu_item_new();
  gtk_widget_show(menu_item);
  gtk_menu_shell_append(GTK_MENU_SHELL(menu_.get()), menu_item);
}

Project: Chrome

GtkWidget* MenuGtk::BuildMenuItemWithImage(const std::string& label,
                                           const SkBitmap& icon) {
  std::string converted_label = ConvertAcceleratorsFromWindowsStyle(label);
  GtkWidget* menu_item =
      gtk_image_menu_item_new_with_mnemonic(converted_label.c_str());

  GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&icon);
  gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),
                                gtk_image_new_from_pixbuf(pixbuf));
  g_object_unref(pixbuf);
  if (delegate_->AlwaysShowImages())
    gtk_util::SetAlwaysShowImage(menu_item);

  return menu_item;
}

Project: Chrome

void MenuGtk::Cancel() {
  gtk_menu_popdown(GTK_MENU(menu_.get()));
}

Project: Chrome

void MenuGtk::ConnectSignalHandlers() {
  g_signal_connect(menu_.get(), "show", G_CALLBACK(OnMenuShow), this);
  g_signal_connect(menu_.get(), "hide", G_CALLBACK(OnMenuHidden), this);
}

Project: Chrome

MenuGtk::MenuGtk(MenuGtk::Delegate* delegate, bool load)
    : delegate_(delegate),
      dummy_accel_group_(NULL),
      menu_(gtk_menu_new()),
      factory_(this) {
  ConnectSignalHandlers();
  if (load)
    BuildMenuFromDelegate();
}

Project: Chrome

void MenuGtk::MenuPositionFunc(GtkMenu* menu,
                               int* x,
                               int* y,
                               gboolean* push_in,
                               void* void_widget) {
  GtkWidget* widget = GTK_WIDGET(void_widget);
  GtkRequisition menu_req;

  gtk_widget_size_request(GTK_WIDGET(menu), &menu_req);

  gdk_window_get_origin(widget->window, x, y);
  GdkScreen *screen = gtk_widget_get_screen(widget);
  gint monitor = gdk_screen_get_monitor_at_point(screen, *x, *y);

  GdkRectangle screen_rect;
  gdk_screen_get_monitor_geometry(screen, monitor,
                                  &screen_rect);

  if (GTK_WIDGET_NO_WINDOW(widget)) {
    *x += widget->allocation.x;
    *y += widget->allocation.y;
  }
  *y += widget->allocation.height;

  bool start_align =
    !!g_object_get_data(G_OBJECT(widget), "left-align-popup");
  if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT)
    start_align = !start_align;

  if (!start_align)
    *x += widget->allocation.width - menu_req.width;

  if (*y + menu_req.height >= screen_rect.height &&
      *y > screen_rect.height / 2) {
    *y -= menu_req.height;
  }

  *push_in = FALSE;
}

Project: Chrome

void MenuGtk::OnMenuHidden(GtkWidget* widget, MenuGtk* menu) {
  menu->delegate_->StoppedShowing();
}

Project: Chrome

void MenuGtk::OnMenuShow(GtkWidget* widget, MenuGtk* menu) {
  MessageLoop::current()->PostTask(FROM_HERE,
      menu->factory_.NewRunnableMethod(&MenuGtk::UpdateMenu));
}

Project: Chrome

void MenuGtk::Popup(GtkWidget* widget, gint button_type, guint32 timestamp) {
  gtk_menu_popup(GTK_MENU(menu_.get()), NULL, NULL,
                 MenuPositionFunc,
                 widget,
                 button_type, timestamp);
}

Project: Chrome

void MenuGtk::PopupAsContext(guint32 event_time) {
  gtk_menu_popup(GTK_MENU(menu_.get()), NULL, NULL, NULL, NULL, 3, event_time);
}

Project: Chrome

void MenuGtk::PopupAsFromKeyEvent(GtkWidget* widget) {
  Popup(widget, 0, gtk_get_current_event_time());
  gtk_menu_shell_select_first(GTK_MENU_SHELL(menu_.get()), FALSE);
}

Project: Chrome

void MenuGtk::SetMenuItemInfo(GtkWidget* widget, gpointer userdata) {
  if (GTK_IS_SEPARATOR_MENU_ITEM(widget)) {
    return;
  }

  MenuGtk* menu = reinterpret_cast<MenuGtk*>(userdata);
  int id;
  const MenuCreateMaterial* data =
      reinterpret_cast<const MenuCreateMaterial*>(
          g_object_get_data(G_OBJECT(widget), "menu-data"));
  if (data) {
    id = data->id;
  } else {
    id = reinterpret_cast<intptr_t>(g_object_get_data(G_OBJECT(widget),
                                    "menu-id"));
  }

  if (GTK_IS_CHECK_MENU_ITEM(widget)) {
    GtkCheckMenuItem* item = GTK_CHECK_MENU_ITEM(widget);

    block_activation_ = true;
    gtk_check_menu_item_set_active(item, menu->delegate_->IsItemChecked(id));
    block_activation_ = false;
  }

  if (GTK_IS_MENU_ITEM(widget)) {
    gtk_widget_set_sensitive(
        widget, menu->delegate_->IsCommandEnabled(id));

    GtkWidget* submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget));
    if (submenu) {
      gtk_container_foreach(GTK_CONTAINER(submenu), &SetMenuItemInfo,
                            userdata);
    }
  }
}

Project: Chrome

void MenuGtk::UpdateMenu() {
  gtk_container_foreach(GTK_CONTAINER(menu_.get()), SetMenuItemInfo, this);
}

Project: Chrome

MenuGtk::~MenuGtk() {
  menu_.Destroy();
  STLDeleteContainerPointers(submenus_we_own_.begin(), submenus_we_own_.end());
  if (dummy_accel_group_)
    g_object_unref(dummy_accel_group_);
}