Skip to content

Commit

Permalink
resize: support for keeping ratio
Browse files Browse the repository at this point in the history
  • Loading branch information
lilydjwg committed Aug 30, 2023
1 parent d485f0d commit 25a8184
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 11 deletions.
6 changes: 6 additions & 0 deletions metadata/resize.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,11 @@
<_long>When the specified button is held down, you can drag windows to resize them.</_long>
<default>&lt;super&gt; BTN_RIGHT</default>
</option>

<option name="activate_preserve_aspect" type="button">
<_short>Activate resize while preserving aspect</_short>
<_long>When the specified button is held down, you can drag windows to resize them while perserving its orignal aspect.</_long>
<default>disabled</default>
</option>
</plugin>
</wayfire>
62 changes: 51 additions & 11 deletions plugins/single_plugins/resize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,19 @@ class wayfire_resize : public wf::per_output_plugin_instance_t, public wf::point
};

wf::button_callback activate_binding;
wf::button_callback activate_binding_preserve_aspect;

wayfire_toplevel_view view;

bool was_client_request, is_using_touch;
bool preserve_aspect = false;
wf::point_t grab_start;
wf::geometry_t grabbed_geometry;

uint32_t edges;
wf::option_wrapper_t<wf::buttonbinding_t> button{"resize/activate"};
wf::option_wrapper_t<wf::buttonbinding_t> button_preserve_aspect{
"resize/activate_preserve_aspect"};
std::unique_ptr<wf::input_grab_t> input_grab;
wf::plugin_activation_data_t grab_interface = {
.name = "resize",
Expand All @@ -72,18 +76,16 @@ class wayfire_resize : public wf::per_output_plugin_instance_t, public wf::point

activate_binding = [=] (auto)
{
auto view = toplevel_cast(wf::get_core().get_cursor_focus_view());
if (view)
{
is_using_touch = false;
was_client_request = false;
initiate(view);
}
return activate(false);
};

return false;
activate_binding_preserve_aspect = [=] (auto)
{
return activate(true);
};

output->add_button(button, &activate_binding);
output->add_button(button_preserve_aspect, &activate_binding_preserve_aspect);
grab_interface.cancel = [=] ()
{
input_pressed(WLR_BUTTON_RELEASED);
Expand All @@ -93,14 +95,29 @@ class wayfire_resize : public wf::per_output_plugin_instance_t, public wf::point
output->connect(&on_view_disappeared);
}

bool activate(bool should_preserve_aspect)
{
auto view = toplevel_cast(wf::get_core().get_cursor_focus_view());
if (view)
{
is_using_touch = false;
was_client_request = false;
preserve_aspect = should_preserve_aspect;
initiate(view);
}

return false;
}

void handle_pointer_button(const wlr_pointer_button_event& event) override
{
if ((event.state == WLR_BUTTON_RELEASED) && was_client_request && (event.button == BTN_LEFT))
{
return input_pressed(event.state);
}

if (event.button != wf::buttonbinding_t(button).get_button())
if ((event.button != wf::buttonbinding_t(button).get_button()) &&
(event.button != wf::buttonbinding_t(button_preserve_aspect).get_button()))
{
return;
}
Expand Down Expand Up @@ -287,6 +304,12 @@ class wayfire_resize : public wf::per_output_plugin_instance_t, public wf::point
int dy = input.y - grab_start.y;

wf::geometry_t desired = grabbed_geometry;
double ratio;
if (preserve_aspect)
{
ratio = (double)desired.width / desired.height;
}

if (edges & WLR_EDGE_LEFT)
{
desired.x += dx;
Expand All @@ -305,8 +328,24 @@ class wayfire_resize : public wf::per_output_plugin_instance_t, public wf::point
desired.height += dy;
}

desired.width = std::max(desired.width, 1);
desired.height = std::max(desired.height, 1);
if (preserve_aspect)
{
auto bbox = desired;
desired.width = std::min(std::max(bbox.width, 1), (int)(bbox.height * ratio));
desired.height = std::min(std::max(bbox.height, 1), (int)(bbox.width / ratio));
if (edges & WLR_EDGE_LEFT)
{
desired.x += bbox.width - desired.width;
}
if (edges & WLR_EDGE_TOP)
{
desired.y += bbox.height - desired.height;
}
} else
{
desired.width = std::max(desired.width, 1);
desired.height = std::max(desired.height, 1);
}

view->toplevel()->pending().gravity = calculate_gravity();
view->toplevel()->pending().geometry = desired;
Expand All @@ -321,6 +360,7 @@ class wayfire_resize : public wf::per_output_plugin_instance_t, public wf::point
}

output->rem_binding(&activate_binding);
output->rem_binding(&activate_binding_preserve_aspect);
}
};

Expand Down

0 comments on commit 25a8184

Please sign in to comment.