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

xwayland: Use configure request mask to position surfaces #308

Merged
merged 1 commit into from
Oct 9, 2019
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
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
39 changes: 30 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,22 @@ 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
{
/* Until the first configure we send to the client, the position
* of the window in the X server and in Wayfire is out-of-sync,
* so we can't rely on the position in the event. */
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 +267,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 +316,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 +521,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