Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(636)

Side by Side Diff: chrome/browser/ui/gtk/browser_window_gtk.cc

Issue 11272015: DevTools: “Dock to right” broken after turning a tab into a window of its own. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: GTK comments addressed, docs updated. Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/gtk/browser_window_gtk.h" 5 #include "chrome/browser/ui/gtk/browser_window_gtk.h"
6 6
7 #include <gdk/gdkkeysyms.h> 7 #include <gdk/gdkkeysyms.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <string> 10 #include <string>
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 112
113 using content::NativeWebKeyboardEvent; 113 using content::NativeWebKeyboardEvent;
114 using content::SSLStatus; 114 using content::SSLStatus;
115 using content::WebContents; 115 using content::WebContents;
116 116
117 namespace { 117 namespace {
118 118
119 // The number of milliseconds between loading animation frames. 119 // The number of milliseconds between loading animation frames.
120 const int kLoadingAnimationFrameTimeMs = 30; 120 const int kLoadingAnimationFrameTimeMs = 30;
121 121
122 // Minimal height of devotools pane or content pane when devtools are docked
123 // to the browser window.
124 const int kMinDevToolsHeight = 50;
125 const int kMinDevToolsWidth = 150;
126 const int kMinContentsSize = 50;
127
128 const char* kBrowserWindowKey = "__BROWSER_WINDOW_GTK__"; 122 const char* kBrowserWindowKey = "__BROWSER_WINDOW_GTK__";
129 123
130 // The frame border is only visible in restored mode and is hardcoded to 4 px 124 // The frame border is only visible in restored mode and is hardcoded to 4 px
131 // on each side regardless of the system window border size. 125 // on each side regardless of the system window border size.
132 const int kFrameBorderThickness = 4; 126 const int kFrameBorderThickness = 4;
133 // While resize areas on Windows are normally the same size as the window 127 // While resize areas on Windows are normally the same size as the window
134 // borders, our top area is shrunk by 1 px to make it easier to move the window 128 // borders, our top area is shrunk by 1 px to make it easier to move the window
135 // around with our thinner top grabbable strip. (Incidentally, our side and 129 // around with our thinner top grabbable strip. (Incidentally, our side and
136 // bottom resize areas don't match the frame border thickness either -- they 130 // bottom resize areas don't match the frame border thickness either -- they
137 // span the whole nonclient area, so there's no "dead zone" for the mouse.) 131 // span the whole nonclient area, so there's no "dead zone" for the mouse.)
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 : window_(NULL), 225 : window_(NULL),
232 window_container_(NULL), 226 window_container_(NULL),
233 window_vbox_(NULL), 227 window_vbox_(NULL),
234 render_area_vbox_(NULL), 228 render_area_vbox_(NULL),
235 render_area_floating_container_(NULL), 229 render_area_floating_container_(NULL),
236 render_area_event_box_(NULL), 230 render_area_event_box_(NULL),
237 toolbar_border_(NULL), 231 toolbar_border_(NULL),
238 browser_(browser), 232 browser_(browser),
239 state_(GDK_WINDOW_STATE_WITHDRAWN), 233 state_(GDK_WINDOW_STATE_WITHDRAWN),
240 devtools_dock_side_(DEVTOOLS_DOCK_SIDE_BOTTOM), 234 devtools_dock_side_(DEVTOOLS_DOCK_SIDE_BOTTOM),
235 devtools_window_(NULL),
241 contents_hsplit_(NULL), 236 contents_hsplit_(NULL),
242 contents_vsplit_(NULL), 237 contents_vsplit_(NULL),
243 frame_cursor_(NULL), 238 frame_cursor_(NULL),
244 is_active_(false), 239 is_active_(false),
245 show_state_after_show_(ui::SHOW_STATE_DEFAULT), 240 show_state_after_show_(ui::SHOW_STATE_DEFAULT),
246 suppress_window_raise_(false), 241 suppress_window_raise_(false),
247 accel_group_(NULL), 242 accel_group_(NULL),
248 fullscreen_exit_bubble_type_( 243 fullscreen_exit_bubble_type_(
249 FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION) { 244 FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION) {
250 } 245 }
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 729
735 void BrowserWindowGtk::BookmarkBarStateChanged( 730 void BrowserWindowGtk::BookmarkBarStateChanged(
736 BookmarkBar::AnimateChangeType change_type) { 731 BookmarkBar::AnimateChangeType change_type) {
737 MaybeShowBookmarkBar(change_type == BookmarkBar::ANIMATE_STATE_CHANGE); 732 MaybeShowBookmarkBar(change_type == BookmarkBar::ANIMATE_STATE_CHANGE);
738 } 733 }
739 734
740 void BrowserWindowGtk::UpdateDevTools() { 735 void BrowserWindowGtk::UpdateDevTools() {
741 UpdateDevToolsForContents(chrome::GetActiveWebContents(browser_.get())); 736 UpdateDevToolsForContents(chrome::GetActiveWebContents(browser_.get()));
742 } 737 }
743 738
744 void BrowserWindowGtk::SetDevToolsDockSide(DevToolsDockSide side) {
745 if (devtools_dock_side_ == side)
746 return;
747
748 if (devtools_container_->tab()) {
749 HideDevToolsContainer();
750 ShowDevToolsContainer(side);
751 } else {
752 devtools_dock_side_ = side;
753 }
754 }
755
756 void BrowserWindowGtk::UpdateLoadingAnimations(bool should_animate) { 739 void BrowserWindowGtk::UpdateLoadingAnimations(bool should_animate) {
757 if (should_animate) { 740 if (should_animate) {
758 if (!loading_animation_timer_.IsRunning()) { 741 if (!loading_animation_timer_.IsRunning()) {
759 // Loads are happening, and the timer isn't running, so start it. 742 // Loads are happening, and the timer isn't running, so start it.
760 loading_animation_timer_.Start(FROM_HERE, 743 loading_animation_timer_.Start(FROM_HERE,
761 base::TimeDelta::FromMilliseconds(kLoadingAnimationFrameTimeMs), this, 744 base::TimeDelta::FromMilliseconds(kLoadingAnimationFrameTimeMs), this,
762 &BrowserWindowGtk::LoadingAnimationCallback); 745 &BrowserWindowGtk::LoadingAnimationCallback);
763 } 746 }
764 } else { 747 } else {
765 if (loading_animation_timer_.IsRunning()) { 748 if (loading_animation_timer_.IsRunning()) {
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 1295
1313 extensions::ActiveTabPermissionGranter* 1296 extensions::ActiveTabPermissionGranter*
1314 BrowserWindowGtk::GetActiveTabPermissionGranter() { 1297 BrowserWindowGtk::GetActiveTabPermissionGranter() {
1315 TabContents* tab = GetDisplayedTab(); 1298 TabContents* tab = GetDisplayedTab();
1316 if (!tab) 1299 if (!tab)
1317 return NULL; 1300 return NULL;
1318 return extensions::TabHelper::FromWebContents(tab->web_contents())-> 1301 return extensions::TabHelper::FromWebContents(tab->web_contents())->
1319 active_tab_permission_granter(); 1302 active_tab_permission_granter();
1320 } 1303 }
1321 1304
1322 void BrowserWindowGtk::UpdateDevToolsForContents(WebContents* contents) {
1323 TRACE_EVENT0("ui::gtk", "BrowserWindowGtk::UpdateDevToolsForContents");
1324 TabContents* old_devtools = devtools_container_->tab();
1325 DevToolsWindow* devtools_window = contents ?
1326 DevToolsWindow::GetDockedInstanceForInspectedTab(contents) : NULL;
1327 TabContents* devtools_contents =
1328 devtools_window ? devtools_window->tab_contents() : NULL;
1329
1330 if (old_devtools == devtools_contents) {
1331 if (devtools_contents &&
1332 devtools_window->dock_side() != devtools_dock_side_)
1333 SetDevToolsDockSide(devtools_window->dock_side());
1334 return;
1335 }
1336
1337 if (old_devtools)
1338 devtools_container_->DetachTab(old_devtools);
1339
1340 devtools_container_->SetTab(devtools_contents);
1341 if (devtools_contents) {
1342 // WebContentsViewGtk::WasShown is not called when tab contents is shown by
1343 // anything other than user selecting a Tab.
1344 // See TabContentsViewViews::OnWindowPosChanged for reference on how it
1345 // should be implemented.
1346 devtools_contents->web_contents()->WasShown();
1347 }
1348
1349 bool should_show = old_devtools == NULL && devtools_contents != NULL;
1350 bool should_hide = old_devtools != NULL && devtools_contents == NULL;
1351
1352 if (should_show)
1353 ShowDevToolsContainer(devtools_window->dock_side());
1354 else if (should_hide)
1355 HideDevToolsContainer();
1356 }
1357
1358 void BrowserWindowGtk::ShowDevToolsContainer(DevToolsDockSide dock_side) {
1359 devtools_dock_side_ = dock_side;
1360 bool dock_to_right = dock_side == DEVTOOLS_DOCK_SIDE_RIGHT;
1361
1362 GtkAllocation contents_rect;
1363 gtk_widget_get_allocation(contents_vsplit_, &contents_rect);
1364 int content_size =
1365 dock_to_right ? contents_rect.width : contents_rect.height;
1366
1367 int split_offset = browser_->profile()->GetPrefs()->
1368 GetInteger(dock_to_right ? prefs::kDevToolsVSplitLocation :
1369 prefs::kDevToolsHSplitLocation);
1370 int min_size =
1371 dock_to_right ? kMinDevToolsWidth : kMinDevToolsHeight;
1372
1373 if (split_offset == -1)
1374 split_offset = content_size * 1 / 3;
1375 // Make sure user can see both panes.
1376 split_offset = std::max(min_size, split_offset);
1377 split_offset = std::min(content_size - kMinContentsSize, split_offset);
1378 if (split_offset < 0)
1379 split_offset = content_size * 1 / 3;
1380 if (dock_to_right) {
1381 gtk_paned_pack2(GTK_PANED(contents_hsplit_), devtools_container_->widget(),
1382 FALSE, TRUE);
1383 gtk_paned_set_position(GTK_PANED(contents_hsplit_),
1384 content_size - split_offset);
1385 } else {
1386 gtk_paned_pack2(GTK_PANED(contents_vsplit_), devtools_container_->widget(),
1387 FALSE, TRUE);
1388 gtk_paned_set_position(GTK_PANED(contents_vsplit_),
1389 content_size - split_offset);
1390 }
1391 gtk_widget_show(devtools_container_->widget());
1392 }
1393
1394 void BrowserWindowGtk::HideDevToolsContainer() {
1395 GtkAllocation contents_rect;
1396 gtk_widget_get_allocation(contents_vsplit_, &contents_rect);
1397 bool dock_to_right = devtools_dock_side_ == DEVTOOLS_DOCK_SIDE_RIGHT;
1398 gint split_offset;
1399 if (dock_to_right) {
1400 split_offset = contents_rect.width -
1401 gtk_paned_get_position(GTK_PANED(contents_hsplit_));
1402 gtk_container_remove(GTK_CONTAINER(contents_hsplit_),
1403 devtools_container_->widget());
1404 } else {
1405 split_offset = contents_rect.height -
1406 gtk_paned_get_position(GTK_PANED(contents_vsplit_));
1407 gtk_container_remove(GTK_CONTAINER(contents_vsplit_),
1408 devtools_container_->widget());
1409 }
1410
1411 browser_->profile()->GetPrefs()->
1412 SetInteger(dock_to_right ? prefs::kDevToolsVSplitLocation :
1413 prefs::kDevToolsHSplitLocation,
1414 split_offset);
1415 }
1416
1417 void BrowserWindowGtk::DestroyBrowser() { 1305 void BrowserWindowGtk::DestroyBrowser() {
1418 browser_.reset(); 1306 browser_.reset();
1419 } 1307 }
1420 1308
1421 gboolean BrowserWindowGtk::OnConfigure(GtkWidget* widget, 1309 gboolean BrowserWindowGtk::OnConfigure(GtkWidget* widget,
1422 GdkEventConfigure* event) { 1310 GdkEventConfigure* event) {
1423 gfx::Rect bounds(event->x, event->y, event->width, event->height); 1311 gfx::Rect bounds(event->x, event->y, event->width, event->height);
1424 1312
1425 // When the window moves, we'll get multiple configure-event signals. We can 1313 // When the window moves, we'll get multiple configure-event signals. We can
1426 // also get events when the bounds haven't changed, but the window's stacking 1314 // also get events when the bounds haven't changed, but the window's stacking
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 1663
1776 status_bubble_.reset(new StatusBubbleGtk(browser_->profile())); 1664 status_bubble_.reset(new StatusBubbleGtk(browser_->profile()));
1777 1665
1778 contents_container_.reset(new TabContentsContainerGtk(status_bubble_.get())); 1666 contents_container_.reset(new TabContentsContainerGtk(status_bubble_.get()));
1779 devtools_container_.reset(new TabContentsContainerGtk(NULL)); 1667 devtools_container_.reset(new TabContentsContainerGtk(NULL));
1780 ViewIDUtil::SetID(devtools_container_->widget(), VIEW_ID_DEV_TOOLS_DOCKED); 1668 ViewIDUtil::SetID(devtools_container_->widget(), VIEW_ID_DEV_TOOLS_DOCKED);
1781 1669
1782 contents_hsplit_ = gtk_hpaned_new(); 1670 contents_hsplit_ = gtk_hpaned_new();
1783 gtk_paned_pack1(GTK_PANED(contents_hsplit_), contents_container_->widget(), 1671 gtk_paned_pack1(GTK_PANED(contents_hsplit_), contents_container_->widget(),
1784 TRUE, TRUE); 1672 TRUE, TRUE);
1785
1786 contents_vsplit_ = gtk_vpaned_new(); 1673 contents_vsplit_ = gtk_vpaned_new();
1787 gtk_paned_pack1(GTK_PANED(contents_vsplit_), contents_hsplit_, TRUE, TRUE); 1674 gtk_paned_pack1(GTK_PANED(contents_vsplit_), contents_hsplit_, TRUE, TRUE);
1788 1675
1789 gtk_box_pack_end(GTK_BOX(render_area_vbox_), 1676 gtk_box_pack_end(GTK_BOX(render_area_vbox_),
1790 contents_vsplit_, TRUE, TRUE, 0); 1677 contents_vsplit_, TRUE, TRUE, 0);
1791 1678
1792 gtk_widget_show_all(render_area_floating_container_); 1679 gtk_widget_show_all(render_area_floating_container_);
1793 render_area_event_box_ = gtk_event_box_new(); 1680 render_area_event_box_ = gtk_event_box_new();
1794 // Set a white background so during startup the user sees white in the 1681 // Set a white background so during startup the user sees white in the
1795 // content area before we get a WebContents in place. 1682 // content area before we get a WebContents in place.
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
2411 bool BrowserWindowGtk::DrawFrameAsActive() const { 2298 bool BrowserWindowGtk::DrawFrameAsActive() const {
2412 if (ui::ActiveWindowWatcherX::WMSupportsActivation()) 2299 if (ui::ActiveWindowWatcherX::WMSupportsActivation())
2413 return is_active_; 2300 return is_active_;
2414 2301
2415 // Since we don't get notifications when the active state of the frame 2302 // Since we don't get notifications when the active state of the frame
2416 // changes, we can't consistently repaint the frame at the right time. Instead 2303 // changes, we can't consistently repaint the frame at the right time. Instead
2417 // we always draw the frame as active. 2304 // we always draw the frame as active.
2418 return true; 2305 return true;
2419 } 2306 }
2420 2307
2308 void BrowserWindowGtk::UpdateDevToolsForContents(WebContents* contents) {
2309 TRACE_EVENT0("ui::gtk", "BrowserWindowGtk::UpdateDevToolsForContents");
2310 DevToolsWindow* new_devtools_window = contents ?
2311 DevToolsWindow::GetDockedInstanceForInspectedTab(contents) : NULL;
2312
2313 // Fast return in case of the same window having same orientation.
2314 if (devtools_window_ == new_devtools_window && (!new_devtools_window ||
2315 new_devtools_window->dock_side() == devtools_dock_side_))
2316 return;
2317
2318 // Replace tab contents.
2319 if (devtools_window_ != new_devtools_window) {
2320 if (devtools_window_)
2321 devtools_container_->DetachTab(devtools_window_->tab_contents());
2322 devtools_container_->SetTab(
2323 new_devtools_window ? new_devtools_window->tab_contents() : NULL);
2324 if (new_devtools_window) {
2325 // WebContentsViewGtk::WasShown is not called when tab contents is shown
2326 // by anything other than user selecting a Tab.
2327 // See TabContentsViewViews::OnWindowPosChanged for reference on how it
2328 // should be implemented.
2329 new_devtools_window->tab_contents()->web_contents()->WasShown();
2330 }
2331 }
2332
2333 // Store last used position.
2334 if (devtools_window_) {
2335 GtkAllocation contents_rect;
2336 gtk_widget_get_allocation(contents_vsplit_, &contents_rect);
2337 if (devtools_dock_side_ == DEVTOOLS_DOCK_SIDE_RIGHT) {
2338 devtools_window_->SetWidth(
2339 contents_rect.width -
2340 gtk_paned_get_position(GTK_PANED(contents_hsplit_)));
2341 } else {
2342 devtools_window_->SetHeight(
2343 contents_rect.height -
2344 gtk_paned_get_position(GTK_PANED(contents_vsplit_)));
2345 }
2346 }
2347
2348 // Show / hide container if necessary. Changing dock orientation is
2349 // hide + show.
2350 bool should_hide = devtools_window_ && (!new_devtools_window ||
2351 devtools_dock_side_ != new_devtools_window->dock_side());
2352 bool should_show = new_devtools_window && (!devtools_window_ || should_hide);
2353
2354 if (should_hide)
2355 HideDevToolsContainer();
2356
2357 devtools_window_ = new_devtools_window;
2358
2359 if (should_show) {
2360 devtools_dock_side_ = new_devtools_window->dock_side();
2361 ShowDevToolsContainer();
2362 } else if (new_devtools_window) {
2363 UpdateDevToolsSplitPosition();
2364 }
2365 }
2366
2367 void BrowserWindowGtk::ShowDevToolsContainer() {
2368 bool to_right = devtools_dock_side_ == DEVTOOLS_DOCK_SIDE_RIGHT;
2369 gtk_paned_pack2(GTK_PANED(to_right ? contents_hsplit_ : contents_vsplit_),
2370 devtools_container_->widget(),
2371 FALSE,
2372 TRUE);
2373 UpdateDevToolsSplitPosition();
2374 gtk_widget_show(devtools_container_->widget());
2375 }
2376
2377 void BrowserWindowGtk::HideDevToolsContainer() {
2378 bool to_right = devtools_dock_side_ == DEVTOOLS_DOCK_SIDE_RIGHT;
2379 gtk_container_remove(GTK_CONTAINER(to_right ? contents_hsplit_ :
2380 contents_vsplit_),
2381 devtools_container_->widget());
2382 }
2383
2384 void BrowserWindowGtk::UpdateDevToolsSplitPosition() {
2385 GtkAllocation contents_rect;
2386 gtk_widget_get_allocation(contents_vsplit_, &contents_rect);
2387
2388 if (devtools_window_->dock_side() == DEVTOOLS_DOCK_SIDE_RIGHT) {
2389 int split_offset = contents_rect.width -
2390 devtools_window_->GetWidth(contents_rect.width);
2391 gtk_paned_set_position(GTK_PANED(contents_hsplit_), split_offset);
2392 } else {
2393 int split_offset = contents_rect.height -
2394 devtools_window_->GetHeight(contents_rect.height);
2395 gtk_paned_set_position(GTK_PANED(contents_vsplit_), split_offset);
2396 }
2397 }
2398
2421 // static 2399 // static
2422 bool BrowserWindowGtk::GetCustomFramePrefDefault() { 2400 bool BrowserWindowGtk::GetCustomFramePrefDefault() {
2423 // Ideally, we'd use the custom frame by default and just fall back on using 2401 // Ideally, we'd use the custom frame by default and just fall back on using
2424 // system decorations for the few (?) tiling window managers where the custom 2402 // system decorations for the few (?) tiling window managers where the custom
2425 // frame doesn't make sense (e.g. awesome, ion3, ratpoison, xmonad, etc.) or 2403 // frame doesn't make sense (e.g. awesome, ion3, ratpoison, xmonad, etc.) or
2426 // other WMs where it has issues (e.g. Fluxbox -- see issue 19130). The EWMH 2404 // other WMs where it has issues (e.g. Fluxbox -- see issue 19130). The EWMH
2427 // _NET_SUPPORTING_WM property makes it easy to look up a name for the current 2405 // _NET_SUPPORTING_WM property makes it easy to look up a name for the current
2428 // WM, but at least some of the WMs in the latter group don't set it. 2406 // WM, but at least some of the WMs in the latter group don't set it.
2429 // Instead, we default to using system decorations for all WMs and 2407 // Instead, we default to using system decorations for all WMs and
2430 // special-case the ones where the custom frame should be used. 2408 // special-case the ones where the custom frame should be used.
2431 ui::WindowManagerName wm_type = ui::GuessWindowManager(); 2409 ui::WindowManagerName wm_type = ui::GuessWindowManager();
2432 return (wm_type == ui::WM_BLACKBOX || 2410 return (wm_type == ui::WM_BLACKBOX ||
2433 wm_type == ui::WM_COMPIZ || 2411 wm_type == ui::WM_COMPIZ ||
2434 wm_type == ui::WM_ENLIGHTENMENT || 2412 wm_type == ui::WM_ENLIGHTENMENT ||
2435 wm_type == ui::WM_METACITY || 2413 wm_type == ui::WM_METACITY ||
2436 wm_type == ui::WM_MUTTER || 2414 wm_type == ui::WM_MUTTER ||
2437 wm_type == ui::WM_OPENBOX || 2415 wm_type == ui::WM_OPENBOX ||
2438 wm_type == ui::WM_XFWM4); 2416 wm_type == ui::WM_XFWM4);
2439 } 2417 }
2440 2418
2441 // static 2419 // static
2442 BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) { 2420 BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) {
2443 BrowserWindowGtk* browser_window_gtk = new BrowserWindowGtk(browser); 2421 BrowserWindowGtk* browser_window_gtk = new BrowserWindowGtk(browser);
2444 browser_window_gtk->Init(); 2422 browser_window_gtk->Init();
2445 return browser_window_gtk; 2423 return browser_window_gtk;
2446 } 2424 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698