# Window Resizer
[WindowResizer](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/window_resizer.h;l=35;drc=719c18366c0226fa751f38693b00f822d1b7ea9b) is an abstract class to describe how to handle dragging, moving or resizing a window.
Let's see what kind of behavior we need to support and what what kind of window types with different resizing logic.
## WindowResizer methods
WindowResizer must have the current window state as `window_state_` which is passed on contruction. Also, it assumes that the window state holds [DragDetails](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/drag_details.h;l=19;drc=719c18366c0226fa751f38693b00f822d1b7ea9b) value. DragDetails is a container of the drag related data such as initial location or window state before dragging or the bounds change and size change direction bitmasks.
[Drag](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/window_resizer.h;l=63;drc=719c18366c0226fa751f38693b00f822d1b7ea9b) is invoked from all drag/move/resize events.
It's a usual mouse move event. Resizing window is also done through mouse event as it's just dragging the edge of the window.
It passes a destination `location` to drag as a gfx::Point and also have a int specifier of event.
[Pinch](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/window_resizer.h;l=68;drc=719c18366c0226fa751f38693b00f822d1b7ea9b) is a two-finger gesture used to expand or shrink the window. This is newly introduced and now only implemented by [PipWindowResizer](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/pip/pip_window_resizer.cc;l=200;drc=719c18366c0226fa751f38693b00f822d1b7ea9b).
Pinch had not been required on chromeos as the usual window does not behave in such way. You use mouse to expand or if mouse input does not exist, which is tablet mode, the window is maximized or snapped. On snapped state, we sometime resize the window by dragging the divider, but this is not pinch behavior either.
Pip window seems to be a first meaningful usage on chromeos to support pinch behavior.
[FlingOrSwipe](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/window_resizer.h;l=77;drc=719c18366c0226fa751f38693b00f822d1b7ea9b) is inboked by flings or sipws to end the drag.
Fling gesture is registered as [Scroll events](https://source.chromium.org/chromium/chromium/src/+/main:ui/events/types/event_type.h;l=58-62;drc=719c18366c0226fa751f38693b00f822d1b7ea9b) which happens at the beginning or at the end of the scroll. Here, scroll is same as the swipe.
[CompleteDrag, RevertDrag](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/window_resizer.h;l=70-74;drc=719c18366c0226fa751f38693b00f822d1b7ea9b) is invoked to complete or revert the current drag event.
These methods must be implemented to add new resizing logic.
## DefaultWindowResizer
[DefaultWindowResizer](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/default_window_resizer.h;l=18;drc=3a215d1e60a3b32928a50d00ea07ae52ea491a16) is a default implementation of WindowResizer.
This is used by [ToplevelWindowEventHandler](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/toplevel_window_event_handler.h;l=41;drc=e398af9ef8be2d8ad4f6afaa45b1bdac94643e6e) which handles dragging and resizing of the usual toplevel window.
This is the basic logic of resizing we experience a lot on laptop.
On [Drag](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/default_window_resizer.cc;l=24;drc=3a215d1e60a3b32928a50d00ea07ae52ea491a16), it receives the new `location` and compares it with the current bounds obtained from `GetTarget()->bounds()`.
If they are different, invoke [SetBoundsDuringResize](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/window_resizer.cc;l=259;drc=719c18366c0226fa751f38693b00f822d1b7ea9b).
Note that we should not simply set the bounds during the resizing behavior since the bounds on the client side does not know about the onging dragging synchronously during the animation. Animation sometimes runs independently from the actual bounds by attaching a new layer to avoid affecting the current window and bounds.
To avoid the bounds inconsistancy, [ShellSurfacePresentationTimeRecorder](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/shell_surface_presentation_time_recorder.cc;l=88;drc=719c18366c0226fa751f38693b00f822d1b7ea9b) handles the configure request properly during resizing by stop the request to be processed until [RequestNext](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/shell_surface_presentation_time_recorder.cc;l=96;drc=719c18366c0226fa751f38693b00f822d1b7ea9b) is invoked.
## Other WindowResizer
[DragWindowResizer](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/drag_window_resizer.h;l=23;drc=aaa9a857a0d80763c67877b4b812c1fd58cabca0) is a window resizer which supports the dragging across displays.
This is implemented by keeping [`next_window_resizer_`](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/drag_window_resizer.h;l=58;drc=719c18366c0226fa751f38693b00f822d1b7ea9b) which corresponds to the next display.
[PipWindowResizer](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/pip/pip_window_resizer.h;l=24;drc=719c18366c0226fa751f38693b00f822d1b7ea9b) controls the pip window resize. Pip window, Picture-in-Picture window, is a chromeos feature to show video or such frame as a separate window and show it in front of other windows.
It also supports dragging and resizing.
The biggest difference against DefaultWindowResizer is that pip window dissapears on fling swipe. There are dismiss codes inside the drag logic which makes it complicated.
[TabletModeFloatWindowResizer](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/float/tablet_mode_float_window_resizer.h;l=14;drc=16fa1784b1eb072240af168ebfa381bde7ab0bbb) implements a window resizer for floated windows in tablet mode. This seems to be similar to pip window, but it has limited support so logic looks simple.
[WorkspaceWindowResizer](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/workspace/workspace_window_resizer.h;l=35;drc=719c18366c0226fa751f38693b00f822d1b7ea9b) is for workspaces. Unlike DefaultWindowResizer, it does not allow vertical movement or resize outside of the work area. This has the most complicated impl on initial look, so will take a look in the future.