Skip to content

Commit

Permalink
xwayland: Use configure request mask to position surfaces
Browse files Browse the repository at this point in the history
The mask contains information about whether or not to use the
position and size fields. Since size is determined by commit,
we only concern ourselves with the position here. This requires
wlroots #1843. This fixes bugs with positioning xwayland surfaces
with and without place plugin enabled. Fixes #307. Thanks to
ammen99 for the initial work on this.
  • Loading branch information
soreau committed Oct 9, 2019
1 parent 6f7e3f0 commit 6bad967
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 71 deletions.
2 changes: 1 addition & 1 deletion plugins/single_plugins/move.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class wf_move_mirror_view : public wf::mirror_view_t
virtual void close()
{
if (show_animation)
emit_view_pre_unmap(self());
emit_view_pre_unmap();

wf::mirror_view_t::close();
}
Expand Down
4 changes: 3 additions & 1 deletion plugins/single_plugins/place.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@ class wayfire_place_window : public wf::plugin_interface_t

created_cb = [=] (wf::signal_data_t *data)
{
auto ev = (map_view_signal*) (data);
auto view = get_signaled_view(data);

if (view->role != wf::VIEW_ROLE_TOPLEVEL || view->parent ||
view->fullscreen || view->tiled_edges)
view->fullscreen || view->tiled_edges || ev->is_positioned)
{
return;
}

ev->is_positioned = true;
auto workarea = output->workspace->get_workarea();
auto mode = placement_mode->as_string();

Expand Down
7 changes: 6 additions & 1 deletion src/api/signal-definitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@ wayfire_view get_signaled_view(wf::signal_data_t *data);

using create_view_signal = _view_signal;
using destroy_view_signal = _view_signal;
using map_view_signal = _view_signal;
using unmap_view_signal = _view_signal;
using pre_unmap_view_signal = _view_signal;

struct map_view_signal : public _view_signal
{
/* Indicates whether the position already has its initial posittion */
bool is_positioned = false;
};

/* Indicates the view is no longer available, for ex. it has been minimized
* or unmapped */
using view_disappeared_signal = _view_signal;
Expand Down
39 changes: 20 additions & 19 deletions src/api/view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,28 +401,29 @@ class view_interface_t : public surface_interface_t, public wf::object_base_t
* Called whenever the minimized, tiled, fullscreened
* or activated state changes */
virtual void desktop_state_updated();
};

/**
* Emit the view map signal. It indicates that a view has been mapped, i.e.
* plugins can now "work" with it. Note that not all views will emit the map
* event.
*/
void emit_view_map(wayfire_view view);
/**
* Emit the view map signal. It indicates that a view has been mapped, i.e.
* plugins can now "work" with it. Note that not all views will emit the map
* event.
*/
virtual void emit_view_map();

/**
* Emit the view unmap signal. It indicates that the view is in the process of
* being destroyed. Most plugins should stop any actions they have on the view.
*/
void emit_view_unmap(wayfire_view view);
/**
* Emit the view unmap signal. It indicates that the view is in the process of
* being destroyed. Most plugins should stop any actions they have on the view.
*/
virtual void emit_view_unmap();

/**
* Emit the view pre-unmap signal. It is emitted right before the view
* destruction start. At this moment a plugin can still take a snapshot of the
* view. Note that not all views emit the pre-unmap signal, however the unmap
* signal is mandatory for all views.
*/
virtual void emit_view_pre_unmap();
};

/**
* Emit the view pre-unmap signal. It is emitted right before the view
* destruction start. At this moment a plugin can still take a snapshot of the
* view. Note that not all views emit the pre-unmap signal, however the unmap
* signal is mandatory for all views.
*/
void emit_view_pre_unmap(wayfire_view view);
wayfire_view wl_surface_to_wayfire_view(wl_resource *surface);
}

Expand Down
6 changes: 3 additions & 3 deletions src/view/compositor-view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ void wf::mirror_view_t::close()
if (!base_view)
return;

emit_view_pre_unmap(self());
emit_view_pre_unmap();

base_view->disconnect_signal("unmap", &base_view_unmapped);
base_view->disconnect_signal("damaged-region", &base_view_damaged);
base_view = nullptr;

emit_map_state_change(this);
emit_view_unmap(self());
emit_view_unmap();

unref();
}
Expand Down Expand Up @@ -138,7 +138,7 @@ void wf::color_rect_view_t::close()
{
this->_is_mapped = false;

emit_view_unmap(self());
emit_view_unmap();
emit_map_state_change(this);

unref();
Expand Down
80 changes: 43 additions & 37 deletions src/view/view-impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,6 @@ void wf::wlr_view_t::commit()
this->last_bounding_box = get_bounding_box();
}

void wf::emit_view_map(wayfire_view view)
{
map_view_signal data;
data.view = view;
view->get_output()->emit_signal("map-view", &data);
view->emit_signal("map", &data);
}

void wf::wlr_view_t::map(wlr_surface *surface)
{
wlr_surface_base_t::map(surface);
Expand All @@ -279,44 +271,18 @@ void wf::wlr_view_t::map(wlr_surface *surface)
}

damage();
emit_view_map(self());
emit_view_map();
/* Might trigger repositioning */
set_toplevel_parent(this->parent);
}

void wf::emit_view_unmap(wayfire_view view)
{
unmap_view_signal data;
data.view = view;

if (view->get_output())
{
view->get_output()->emit_signal("unmap-view", &data);
view->get_output()->emit_signal("view-disappeared", &data);
}

view->emit_signal("unmap", &data);
view->emit_signal("disappeared", &data);
}

void wf::emit_view_pre_unmap(wayfire_view view)
{
pre_unmap_view_signal data;
data.view = view;

if (view->get_output())
view->get_output()->emit_signal("pre-unmap-view", &data);

view->emit_signal("pre-unmap", &data);
}

void wf::wlr_view_t::unmap()
{
damage();
/* Pre-unmap is typically used for animations. If the view is a regular
* toplevel view, we don't need to animate */
if (this->role == wf::VIEW_ROLE_TOPLEVEL)
emit_view_pre_unmap(self());
emit_view_pre_unmap();

destroy_toplevel();

Expand All @@ -329,7 +295,47 @@ void wf::wlr_view_t::unmap()
c->set_toplevel_parent(nullptr);

wlr_surface_base_t::unmap();
emit_view_unmap(self());
emit_view_unmap();
}

void wf::emit_view_map_signal(wayfire_view view, bool has_position)
{
map_view_signal data;
data.view = view;
data.is_positioned = has_position;
view->get_output()->emit_signal("map-view", &data);
view->emit_signal("map", &data);
}

void wf::view_interface_t::emit_view_map()
{
emit_view_map_signal(self(), false);
}

void wf::view_interface_t::emit_view_unmap()
{
unmap_view_signal data;
data.view = self();

if (get_output())
{
get_output()->emit_signal("unmap-view", &data);
get_output()->emit_signal("view-disappeared", &data);
}

emit_signal("unmap", &data);
emit_signal("disappeared", &data);
}

void wf::view_interface_t::emit_view_pre_unmap()
{
pre_unmap_view_signal data;
data.view = self();

if (get_output())
get_output()->emit_signal("pre-unmap-view", &data);

emit_signal("pre-unmap", &data);
}

void wf::wlr_view_t::destroy()
Expand Down
3 changes: 3 additions & 0 deletions src/view/view-impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ class wlr_view_t :
}
};

/** Emit the map signal for the given view */
void emit_view_map_signal(wayfire_view view, bool has_position);

wf::surface_interface_t* wf_surface_from_void(void *handle);
wf::view_interface_t* wf_view_from_void(void *handle);

Expand Down
36 changes: 27 additions & 9 deletions src/view/xwayland.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class wayfire_xwayland_view_base : public wf::wlr_view_t
int last_server_width = 0;
int last_server_height = 0;

/** The geometry requested by the client */
bool self_positioned = false;

wf::signal_callback_t output_geometry_changed =
[this] (wf::signal_data_t*)
{
Expand All @@ -49,6 +52,19 @@ class wayfire_xwayland_view_base : public wf::wlr_view_t
on_destroy.set_callback([&] (void*) { destroy(); });
on_configure.set_callback([&] (void* data) {
auto ev = static_cast<wlr_xwayland_surface_configure_event*> (data);
if ((ev->mask & XCB_CONFIG_WINDOW_X) && (ev->mask & XCB_CONFIG_WINDOW_Y))
{
self_positioned = true;
} else
{
auto o = get_output();
if (o)
{
auto og = get_output()->get_layout_geometry();
ev->x = geometry.x + og.x;
ev->y = geometry.y + og.y;
}
}
configure_request({ev->x, ev->y, ev->width, ev->height});
});
on_set_title.set_callback([&] (void*) {
Expand Down Expand Up @@ -248,6 +264,16 @@ class wayfire_xwayland_view : public wayfire_xwayland_view_base
wayfire_xwayland_view_base::destroy();
}

void emit_view_map() override
{
/* Some X clients position themselves on map, and others let the window
* manager determine this. We try to heuristically guess which of the
* two cases we're dealing with by checking whether we have recevied
* a valid ConfigureRequest before mapping */
bool client_self_positioned = self_positioned;
emit_view_map_signal(self(), client_self_positioned);
}

void map(wlr_surface *surface) override
{
/* override-redirect status changed between creation and MapNotify */
Expand Down Expand Up @@ -287,14 +313,6 @@ class wayfire_xwayland_view : public wayfire_xwayland_view_base
if (xw->fullscreen)
fullscreen_request(get_output(), true);

auto real_output = get_output()->get_layout_geometry();
if (!tiled_edges && !fullscreen && !parent)
{
int desired_x = xw->x - real_output.x;
int desired_y = xw->y - real_output.y;
move(desired_x, desired_y);
}

wf::wlr_view_t::map(surface);
create_toplevel();
}
Expand Down Expand Up @@ -500,7 +518,7 @@ void wayfire_unmanaged_xwayland_view::unmap()
/* O-R focuseable views are treated like normal windows, i.e they have the
* pre-unmap event and have unmap animations */
if (view_impl->keyboard_focus_enabled)
emit_view_pre_unmap(self());
emit_view_pre_unmap();

wf::wlr_view_t::unmap();
}
Expand Down

0 comments on commit 6bad967

Please sign in to comment.