Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Window movement to be initiated by Wayland clients (Fixes #61) #171

Merged
merged 4 commits into from
Feb 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 51 additions & 26 deletions examples/miral-shell/floating_window_manager.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright © 2016-2017 Canonical Ltd.
* Copyright © 2016-2018 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 or 3 as
Expand Down Expand Up @@ -77,15 +77,11 @@ bool FloatingWindowManagerPolicy::handle_pointer_event(MirPointerEvent const* ev
bool consumes_event = false;
bool is_resize_event = false;

if (action == mir_pointer_action_button_down)
if (moving)
{
if (auto const window = tools.window_at(cursor))
tools.select_active_window(window);
}
else if (action == mir_pointer_action_motion &&
modifiers == mir_input_event_modifier_alt)
{
if (mir_pointer_event_button_state(event, mir_pointer_button_primary))
if (action == mir_pointer_action_motion &&
modifiers == move_modifiers &&
mir_pointer_event_button_state(event, mir_pointer_button_primary))
{
if (auto const target = tools.window_at(old_cursor))
{
Expand All @@ -94,7 +90,40 @@ bool FloatingWindowManagerPolicy::handle_pointer_event(MirPointerEvent const* ev
}
consumes_event = true;
}
else
moving = false;
}
else if (action == mir_pointer_action_button_down)
{
if (auto const window = tools.window_at(cursor))
tools.select_active_window(window);

if (mir_pointer_event_button_state(event, mir_pointer_button_primary))
{
if (modifiers == mir_input_event_modifier_alt)
{
moving = true;
move_modifiers = modifiers;
consumes_event = true;
}
else if (modifiers == 0)
{
if (auto const possible_titlebar = tools.window_at(old_cursor))
{
auto const& info = tools.info_for(possible_titlebar);
if (decoration_provider->is_titlebar(info))
{
moving = true;
move_modifiers = modifiers;
consumes_event = true;
}
}
}
}
}
else if (action == mir_pointer_action_motion &&
modifiers == mir_input_event_modifier_alt)
{
if (mir_pointer_event_button_state(event, mir_pointer_button_tertiary))
{
{ // Workaround for lp:1627697
Expand All @@ -112,23 +141,6 @@ bool FloatingWindowManagerPolicy::handle_pointer_event(MirPointerEvent const* ev
}
}

if (!consumes_event && action == mir_pointer_action_motion && !modifiers)
{
if (mir_pointer_event_button_state(event, mir_pointer_button_primary))
{
if (auto const possible_titlebar = tools.window_at(old_cursor))
{
auto const& info = tools.info_for(possible_titlebar);
if (decoration_provider->is_titlebar(info))
{
if (tools.select_active_window(info.parent()) == info.parent())
tools.drag_active_window(cursor - old_cursor);
consumes_event = true;
}
}
}
}

if (resizing && !is_resize_event)
end_resize();

Expand Down Expand Up @@ -812,3 +824,16 @@ void FloatingWindowManagerPolicy::handle_modify_window(WindowInfo& window_info,
CanonicalWindowManagerPolicy::handle_modify_window(window_info, mods);
}

void FloatingWindowManagerPolicy::handle_request_drag_and_drop(WindowInfo& /*window_info*/)
{
}

void FloatingWindowManagerPolicy::handle_request_move(WindowInfo& /*window_info*/, MirInputEvent const* input_event)
{
if (mir_input_event_get_type(input_event) == mir_input_event_type_pointer)
{
moving = true;
move_modifiers = mir_pointer_event_modifiers(mir_input_event_get_pointer_event(input_event)) & modifier_mask;
}
}

15 changes: 13 additions & 2 deletions examples/miral-shell/floating_window_manager.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright © 2016-2017 Canonical Ltd.
* Copyright © 2016-2018 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 or 3 as
Expand All @@ -20,6 +20,7 @@
#define MIRAL_SHELL_FLOATING_WINDOW_MANAGER_H

#include <miral/canonical_window_manager.h>
#include <miral/window_management_policy_addendum2.h>
#include <miral/window_management_policy_addendum3.h>
#include <miral/workspace_policy.h>

Expand All @@ -36,7 +37,8 @@ using namespace mir::geometry;
class DecorationProvider;

class FloatingWindowManagerPolicy : public miral::CanonicalWindowManagerPolicy,
public miral::WorkspacePolicy, public miral::WindowManagementPolicyAddendum3
public miral::WorkspacePolicy, public miral::WindowManagementPolicyAddendum3,
public miral::WindowManagementPolicyAddendum2
{
public:
FloatingWindowManagerPolicy(
Expand Down Expand Up @@ -78,6 +80,13 @@ class FloatingWindowManagerPolicy : public miral::CanonicalWindowManagerPolicy,
void handle_modify_window(miral::WindowInfo& window_info, miral::WindowSpecification const& modifications) override;
/** @} */

/** @name support for CSD invoked sizing and movement
* @{ */
void handle_request_drag_and_drop(miral::WindowInfo& window_info) override;

void handle_request_move(miral::WindowInfo& window_info, MirInputEvent const* input_event) override;
/** @} */

protected:
static const int modifier_mask =
mir_input_event_modifier_alt |
Expand All @@ -93,6 +102,8 @@ class FloatingWindowManagerPolicy : public miral::CanonicalWindowManagerPolicy,

Point old_cursor{};

bool moving = false;
unsigned move_modifiers = 0;
bool resizing = false;
bool left_resize = false;
bool top_resize = false;
Expand Down
5 changes: 5 additions & 0 deletions src/server/frontend/wayland/basic_surface_event_sink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ void mf::BasicSurfaceEventSink::handle_event(MirEvent const& event)
case mir_event_type_input:
{
auto input_event = mir_event_get_input_event(&event);

// Remember the timestamp of any events "signed" with a cookie
if (mir_input_event_has_cookie(input_event))
timestamp = mir_input_event_get_event_time(input_event);

switch (mir_input_event_get_type(input_event))
{
case mir_input_event_type_key:
Expand Down
6 changes: 6 additions & 0 deletions src/server/frontend/wayland/basic_surface_event_sink.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ class BasicSurfaceEventSink : public NullEventSink
this->window_size = window_size;
}

auto latest_timestamp() const -> uint64_t
{
return timestamp;
}

virtual void send_resize(geometry::Size const& new_size) const = 0;

protected:
Expand All @@ -72,6 +77,7 @@ class BasicSurfaceEventSink : public NullEventSink
wl_resource* const target;
wl_resource* const event_sink;
std::atomic<geometry::Size> window_size;
std::atomic<int64_t> timestamp{0};
};
}
}
Expand Down
29 changes: 24 additions & 5 deletions src/server/frontend/wayland/wayland_connector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1730,6 +1730,13 @@ class WlShellSurface : public wayland::ShellSurface, WlAbstractMirWindow

void move(struct wl_resource* /*seat*/, uint32_t /*serial*/) override
{
if (surface_id.as_value())
{
if (auto session = session_for_client(client))
{
shell->request_operation(session, surface_id, sink->latest_timestamp(), Shell::UserRequest::move);
}
}
}

void resize(struct wl_resource* /*seat*/, uint32_t /*serial*/, uint32_t /*edges*/) override
Expand Down Expand Up @@ -1877,11 +1884,7 @@ struct XdgToplevelV6 : wayland::XdgToplevelV6
// TODO
}

void move(struct wl_resource* seat, uint32_t serial) override
{
(void)seat, (void)serial;
// TODO
}
void move(struct wl_resource* seat, uint32_t serial) override;

void resize(struct wl_resource* seat, uint32_t serial, uint32_t edges) override
{
Expand Down Expand Up @@ -2067,6 +2070,7 @@ struct XdgSurfaceV6 : wayland::XdgSurfaceV6, WlAbstractMirWindow

void set_parent(optional_value<SurfaceId> parent_id);
void set_title(std::string const& title);
void move(struct wl_resource* seat, uint32_t serial);
void set_max_size(int32_t width, int32_t height);
void set_min_size(int32_t width, int32_t height);
void set_maximized();
Expand Down Expand Up @@ -2108,6 +2112,16 @@ void XdgSurfaceV6::set_title(std::string const& title)
}
}

void XdgSurfaceV6::move(struct wl_resource* /*seat*/, uint32_t /*serial*/)
{
if (surface_id.as_value())
{
if (auto session = session_for_client(client))
{
shell->request_operation(session, surface_id, sink->latest_timestamp(), Shell::UserRequest::move);
}
}
}

void XdgSurfaceV6::set_parent(optional_value<SurfaceId> parent_id)
{
Expand Down Expand Up @@ -2210,6 +2224,11 @@ void XdgToplevelV6::set_title(std::string const& title)
self->set_title(title);
}

void XdgToplevelV6::move(struct wl_resource* seat, uint32_t serial)
{
self->move(seat, serial);
}

void XdgToplevelV6::set_max_size(int32_t width, int32_t height)
{
self->set_max_size(width, height);
Expand Down