15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/libgtk2ui/gtk2_util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <gdk/gdk.h> 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <gdk/gdkx.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtk/gtk.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/environment.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/aura/window.h" 15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/aura/window_tree_host.h" 16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ui/base/accelerators/accelerator.h" 17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_constants.h" 18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/keycodes/keyboard_code_conversion_x.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst char kAuraTransientParent[] = "aura-transient-parent"; 24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommonInitFromCommandLine(const CommandLine& command_line, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*init_func)(gint*, gchar***)) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<std::string>& args = command_line.argv(); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc = args.size(); 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<char *[]> argv(new char *[argc + 1]); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < args.size(); ++i) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(piman@google.com): can gtk_init modify argv? Just being safe 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) argv[i] = strdup(args[i].c_str()); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) argv[argc] = NULL; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char **argv_pointer = argv.get(); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_func(&argc, &argv_pointer); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < args.size(); ++i) { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(argv[i]); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace libgtk2ui { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GtkInitFromCommandLine(const CommandLine& command_line) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommonInitFromCommandLine(command_line, gtk_init); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// TODO(erg): This method was copied out of shell_integration_linux.cc. Because 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// of how this library is structured as a stand alone .so, we can't call code 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// from browser and above. 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string GetDesktopName(base::Environment* env) { 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(GOOGLE_CHROME_BUILD) 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return "google-chrome.desktop"; 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#else // CHROMIUM_BUILD 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Allow $CHROME_DESKTOP to override the built-in value, so that development 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // versions can set themselves as the default without interfering with 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // non-official, packaged versions using the built-in value. 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string name; 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (env->GetVar("CHROME_DESKTOP", &name) && !name.empty()) 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return name; 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return "chromium-browser.desktop"; 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid SetAlwaysShowImage(GtkWidget* image_menu_item) { 70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch gtk_image_menu_item_set_always_show_image( 71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GTK_IMAGE_MENU_ITEM(image_menu_item), TRUE); 72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochguint GetGdkKeyCodeForAccelerator(const ui::Accelerator& accelerator) { 75ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // The second parameter is false because accelerator keys are expressed in 76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // terms of the non-shift-modified key. 77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return XKeysymForWindowsKeyCode(accelerator.key_code(), false); 78ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 79ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 80ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochGdkModifierType GetGdkModifierForAccelerator( 81ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const ui::Accelerator& accelerator) { 82ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int event_flag = accelerator.modifiers(); 83ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int modifier = 0; 84ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (event_flag & ui::EF_SHIFT_DOWN) 85ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch modifier |= GDK_SHIFT_MASK; 86ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (event_flag & ui::EF_CONTROL_DOWN) 87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch modifier |= GDK_CONTROL_MASK; 88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (event_flag & ui::EF_ALT_DOWN) 89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch modifier |= GDK_MOD1_MASK; 90ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return static_cast<GdkModifierType>(modifier); 91ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 92ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 93ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochint EventFlagsFromGdkState(guint state) { 94ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int flags = ui::EF_NONE; 95ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch flags |= (state & GDK_LOCK_MASK) ? ui::EF_CAPS_LOCK_DOWN : ui::EF_NONE; 96ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch flags |= (state & GDK_CONTROL_MASK) ? ui::EF_CONTROL_DOWN : ui::EF_NONE; 97ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch flags |= (state & GDK_SHIFT_MASK) ? ui::EF_SHIFT_DOWN : ui::EF_NONE; 98ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch flags |= (state & GDK_MOD1_MASK) ? ui::EF_ALT_DOWN : ui::EF_NONE; 99ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch flags |= (state & GDK_BUTTON1_MASK) ? ui::EF_LEFT_MOUSE_BUTTON : ui::EF_NONE; 100ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch flags |= 101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch (state & GDK_BUTTON2_MASK) ? ui::EF_MIDDLE_MOUSE_BUTTON : ui::EF_NONE; 102ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch flags |= (state & GDK_BUTTON3_MASK) ? ui::EF_RIGHT_MOUSE_BUTTON : ui::EF_NONE; 103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return flags; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 106c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid SetGtkTransientForAura(GtkWidget* dialog, aura::Window* parent) { 10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!parent || !parent->GetHost()) 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gtk_widget_realize(dialog); 111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GdkWindow* gdk_window = gtk_widget_get_window(dialog); 112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // TODO(erg): Check to make sure we're using X11 if wayland or some other 114c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // display server ever happens. Otherwise, this will crash. 115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch XSetTransientForHint(GDK_WINDOW_XDISPLAY(gdk_window), 116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GDK_WINDOW_XID(gdk_window), 117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch parent->GetHost()->GetAcceleratedWidget()); 118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // We also set the |parent| as a property of |dialog|, so that we can unlink 120c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // the two later. 121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, parent); 122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochaura::Window* GetAuraTransientParent(GtkWidget* dialog) { 125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return reinterpret_cast<aura::Window*>( 126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch g_object_get_data(G_OBJECT(dialog), kAuraTransientParent)); 127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ClearAuraTransientParent(GtkWidget* dialog) { 130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, NULL); 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)GtkStateType GetGtkState(ui::NativeTheme::State state) { 134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) switch (state) { 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case ui::NativeTheme::kDisabled: return GTK_STATE_INSENSITIVE; 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case ui::NativeTheme::kHovered: return GTK_STATE_PRELIGHT; 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case ui::NativeTheme::kNormal: return GTK_STATE_NORMAL; 138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case ui::NativeTheme::kPressed: return GTK_STATE_ACTIVE; 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case ui::NativeTheme::kNumStates: NOTREACHED(); 140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return GTK_STATE_NORMAL; 142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace libgtk2ui 145