blob: 0a8140e9668480a4890ca7a96f680dc96835bfb7 [file] [log] [blame] [view]
andybons3322f762015-08-24 21:37:091# Browser View Resizer
2
3To fix bug [458](http://code.google.com/p/chromium/issues/detail?id=458), which
4identifies that it is hard to hit the thin window frame corner to resize the
5window. It would be better to have a resize hit area (called widget from now on)
6in the corner, as we currently have for edit boxes for example.
7
8[TOC]
9
10## Background
11
12This is specific to the Windows OS. On the Mac, Cocoa automatically adds a
13resize widget (Not sure about Linux, we should double check). On Windows, those
14resize widgets are at the extreme right of a status bar. For example, if you
15remove the status bar from a Windows Explorer window, you lose the resize
16widget. But since Chrome never ever has a status bar and simply take over the
17bottom of the window for specific tasks (like the download shelf for example),
18we need to find a creative way of giving access to a resize widget.
19
20The bottom corners where we would like to add the resize widget are currently
21controlled by the browser view, which can have either the tab contents view or
22other dynamic views (like the download shelf view) displayed in this area.
23
24## Requirements
25
26Since there is no status bar to simply fix a resize widget to, we must
27dynamically create a widget that can be laid either on the tab contents view or
28on other views that might temporarily take over the bottom part of the browser
29view.
30
31When no dynamic view is taking over the bottom of the browser view, the resize
32widget can sit in the bottom right corner of the tab contents view, over the tab
33contents view.
34
35![Resize Corner](http://lh6.ggpht.com/_2OD0ww7UZAs/SUAaNi6TWYI/AAAAAAAAGmI/89jCYQ1Cxsw/ResizeCorner-2.png)
36
37The resize widget must have the same width and height as
38the scroll bars so that it can fit in the corner currently left empty when both
39scroll bars are visible. If only one scroll bar is visible (either the
40horizontal or the vertical one), that scroll bar must still leave room for the
41resize widget to fit there (as it currently leave room for the empty corner when
42both scroll bars are visible), yet, only when the resize widget is laid on top
43of the tab contents view, not when a dynamic shelf is added at the bottom of the
44browser view.
45
46![Resize Corner](http://lh6.ggpht.com/_2OD0ww7UZAs/SUAaNjqr_iI/AAAAAAAAGmA/56hzjdnkVRI/ResizeCorner-1.png)
47![Resize Corner](http://lh3.ggpht.com/_2OD0ww7UZAs/SUAaN_wDEUI/AAAAAAAAGmQ/7B4CTZTXOmk/ResizeCorner-3.png)
48![Resize Corner](http://lh6.ggpht.com/_2OD0ww7UZAs/SUAaN7yme9I/AAAAAAAAGmY/EaniiAbwi-Q/ResizeCorner-4.png)
49
50If another view (e.g., again, the download shelf) is added at the bottom of the
51browser view, below the tab contents view, and covers the bottom corners, then
52the resize widget must be laid on top of this other child view. Of course, all
53child views that can potentially be added at the bottom of the browser view,
54must be designed in a way that leaves enough room in the bottom corners for the
55resize widget.
56
57![Resize Corner](http://lh3.ggpht.com/_2OD0ww7UZAs/SUAaN17TIrI/AAAAAAAAGmg/6bljNQ_vZkI/ResizeCorner-5.png)
58![Resize Corner](http://lh4.ggpht.com/_2OD0ww7UZAs/SUAaWINHA6I/AAAAAAAAGmo/-VG5FGC8Xds/ResizeCorner-6.png)
59![Resize Corner](http://lh6.ggpht.com/_2OD0ww7UZAs/SUAaWDUpo0I/AAAAAAAAGmw/8USPzoMpgu0/ResizeCorner-7.png)
60
61Since the bottom corners might have different colors, based on the state and
62content of the browser view, the resize widget must have a transparent
63background.
64
65The resize widget is not animated itself. It might move with the animation of
66the view it is laid on top of (e.g., when the download shelf is being animated
67in), but we won't attempt to animate the resize widget itself (or fix it in the
68bottom right corner of the browser view while the other views get animated it).
69
70## Design
71
72Unfortunately, we must deal with the two different cases (with or without a
73dynamic bottom view) in two different and distinct ways.
74
75### Over a Dynamic View
76
77For the cases where there is a dynamic view at the bottom of the browser view, a
78new view class (named `BrowserResizerView`) inheriting from
xiaoyin.l1003c0b2016-12-06 02:51:1779[views::View](https://src.chromium.org/svn/trunk/src/chrome/views/view.h) is used
andybons3322f762015-08-24 21:37:0980to display the resize widget. It is set as a child of the dynamic view laid at
81the bottom of the browser view. The Browser view takes care of properly setting
82the bounds of the resize widget view, based on the language direction.
83
84Also, it is easier and more efficient to let the browser view handle the mouse
85interactions to resize the browser. We can let Windows take care of properly
86resizing the view by returning the HTBOTTOMLEFT or HTBOTTOMRIGHT flags from the
87NCClientHitTest windows message handler when they occur over the resize widget.
88The browser view also takes care of changing the mouse cursor to the appropriate
89resizing arrows when the mouse hovers over the resize widget area.
90
91### Without a Dynamic View
92
93To make sure that the scroll bars (handled by `WebKit`) are not drawn on top of
94the resizer widget (or vice versa), we need to properly implement the callback
qyearsleyc0dc6f42016-12-02 22:13:3995specifying the rectangle covered by the resizer. This callback is implemented
andybons3322f762015-08-24 21:37:0996on the `RenderWidget` class that can delegate to a derive class via a new
97virtual method which returns an empty rect on the base class. Via a series of
98delegate interface calls, we eventually get back to the browser view which can
99return the size and position of the resize widget, but only if it is laid out on
100top of the tabs view, it returns an empty rect when there is a dynamic view.
101
102To handle the drawing of the resize widget over the render widget, we need to
103add code to the Windows specific version of the render widget host view which
104receives the bitmap rendered by WebKit so it can layer the transparent bitmap
105used for the resize widget. That same render widget host view must also handle
106the mouse interaction and use the same trick as the browser view to let Windows
107take care of resizing the whole frame. It must also take care of changing the
108mouse cursor to the appropriate resizing arrows when the mouse hovers over the
109resize widget area.
110
111## Implementation
112
113You can find the changes made to make this work in patch
xiaoyin.l1003c0b2016-12-06 02:51:17114[16488](https://codereview.chromium.org/16488).
andybons3322f762015-08-24 21:37:09115
116## Alternatives Considered
117
118We could have tried to reuse the code that currently takes care of resizing the
119edit boxes within WebKit, but this code is wired to the overflow style of HTML
120element and would have been hard to rewire in an elegant way to be used in a
121higher level object like the browser view. Unless we missed something.
122
123We might also decide to go with the easier solution of only showing the resize
124corner within the tab contents view. In that case, it would still be recommended
125that the resize widget would not appear when dynamic views are taking over the
126bottom portion of the browser view, since it would look weird to have a resize
127corner widget that is not in the real... corner... of the browser view ;-)
128
129We may decide that we don't want to see the resize widget bitmap hide some
130pixels from the tab contents (or dynamic view) yet we would still have the
131resizing functionality via the mouse interaction and also get visual feedback
132with the mouse cursor changes while we hover over the resize widget area.
133
134We may do more research to find a way to solve this problem in a single place as
135opposed to the current dual solution, but none was found so far.