mirror of
https://gitlab.freedesktop.org/wayland/weston
synced 2024-10-03 02:23:16 +00:00
xwm: let the shells decide the position of X windows
The xwm used to automatically send to Xwayland the position of X windows when that changed, using the x,y of the primary view of the surface. This works fine for the desktop shell but less so for others. This patch adds a 'send_position' vfunc to the weston_shell_client that the shell will call when it wants to let Xwayland know what the position of a window is. The logic used by the desktop-shell for that is exactly the same the xwm used to have. Reviewed-by: Derek Foreman <derekf@osg.samsung.com> Reviewed-by: David Fort <contact@hardening-consulting.com>
This commit is contained in:
parent
c112e0c5bc
commit
f05d18f3ee
|
@ -1813,7 +1813,8 @@ send_configure(struct weston_surface *surface, int32_t width, int32_t height)
|
|||
}
|
||||
|
||||
static const struct weston_shell_client shell_client = {
|
||||
send_configure
|
||||
send_configure,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -3704,12 +3705,6 @@ create_shell_surface(void *shell, struct weston_surface *surface,
|
|||
return create_common_surface(NULL, shell, surface, client);
|
||||
}
|
||||
|
||||
static struct weston_view *
|
||||
get_primary_view(void *shell, struct shell_surface *shsurf)
|
||||
{
|
||||
return shsurf->view;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_get_shell_surface(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
|
@ -3995,7 +3990,8 @@ xdg_send_configure(struct weston_surface *surface,
|
|||
}
|
||||
|
||||
static const struct weston_shell_client xdg_client = {
|
||||
xdg_send_configure
|
||||
xdg_send_configure,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -4119,7 +4115,8 @@ xdg_popup_send_configure(struct weston_surface *surface,
|
|||
}
|
||||
|
||||
static const struct weston_shell_client xdg_popup_client = {
|
||||
xdg_popup_send_configure
|
||||
xdg_popup_send_configure,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct shell_surface *
|
||||
|
@ -5411,6 +5408,27 @@ wake_handler(struct wl_listener *listener, void *data)
|
|||
unlock(shell);
|
||||
}
|
||||
|
||||
static void
|
||||
transform_handler(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct weston_surface *surface = data;
|
||||
struct shell_surface *shsurf = get_shell_surface(surface);
|
||||
struct weston_view *view;;
|
||||
int x, y;
|
||||
|
||||
if (!shsurf || !shsurf->client->send_position)
|
||||
return;
|
||||
|
||||
view = shsurf->view;
|
||||
if (!view || !weston_view_is_mapped(view))
|
||||
return;
|
||||
|
||||
x = view->geometry.x;
|
||||
y = view->geometry.y;
|
||||
|
||||
shsurf->client->send_position(surface, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
center_on_output(struct weston_view *view, struct weston_output *output)
|
||||
{
|
||||
|
@ -6379,6 +6397,7 @@ shell_destroy(struct wl_listener *listener, void *data)
|
|||
|
||||
wl_list_remove(&shell->idle_listener.link);
|
||||
wl_list_remove(&shell->wake_listener.link);
|
||||
wl_list_remove(&shell->transform_listener.link);
|
||||
|
||||
text_backend_destroy(shell->text_backend);
|
||||
input_panel_destroy(shell);
|
||||
|
@ -6520,10 +6539,11 @@ module_init(struct weston_compositor *ec,
|
|||
wl_signal_add(&ec->idle_signal, &shell->idle_listener);
|
||||
shell->wake_listener.notify = wake_handler;
|
||||
wl_signal_add(&ec->wake_signal, &shell->wake_listener);
|
||||
shell->transform_listener.notify = transform_handler;
|
||||
wl_signal_add(&ec->transform_signal, &shell->transform_listener);
|
||||
|
||||
ec->shell_interface.shell = shell;
|
||||
ec->shell_interface.create_shell_surface = create_shell_surface;
|
||||
ec->shell_interface.get_primary_view = get_primary_view;
|
||||
ec->shell_interface.set_toplevel = set_toplevel;
|
||||
ec->shell_interface.set_transient = set_transient;
|
||||
ec->shell_interface.set_fullscreen = shell_interface_set_fullscreen;
|
||||
|
|
|
@ -121,6 +121,7 @@ struct desktop_shell {
|
|||
|
||||
struct wl_listener idle_listener;
|
||||
struct wl_listener wake_listener;
|
||||
struct wl_listener transform_listener;
|
||||
struct wl_listener destroy_listener;
|
||||
struct wl_listener show_input_panel_listener;
|
||||
struct wl_listener hide_input_panel_listener;
|
||||
|
|
|
@ -86,6 +86,7 @@ struct weston_mode {
|
|||
|
||||
struct weston_shell_client {
|
||||
void (*send_configure)(struct weston_surface *surface, int32_t width, int32_t height);
|
||||
void (*send_position)(struct weston_surface *surface, int32_t x, int32_t y);
|
||||
};
|
||||
|
||||
struct weston_shell_interface {
|
||||
|
@ -94,9 +95,6 @@ struct weston_shell_interface {
|
|||
struct shell_surface *(*create_shell_surface)(void *shell,
|
||||
struct weston_surface *surface,
|
||||
const struct weston_shell_client *client);
|
||||
struct weston_view *(*get_primary_view)(void *shell,
|
||||
struct shell_surface *shsurf);
|
||||
|
||||
void (*set_toplevel)(struct shell_surface *shsurf);
|
||||
|
||||
void (*set_transient)(struct shell_surface *shsurf,
|
||||
|
|
|
@ -145,6 +145,7 @@ struct weston_wm_window {
|
|||
xcb_atom_t type;
|
||||
int width, height;
|
||||
int x, y;
|
||||
bool pos_dirty;
|
||||
int saved_width, saved_height;
|
||||
int decorate;
|
||||
int override_redirect;
|
||||
|
@ -692,6 +693,8 @@ weston_wm_handle_configure_notify(struct weston_wm *wm, xcb_generic_event_t *eve
|
|||
|
||||
window->x = configure_notify->x;
|
||||
window->y = configure_notify->y;
|
||||
window->pos_dirty = false;
|
||||
|
||||
if (window->override_redirect) {
|
||||
window->width = configure_notify->width;
|
||||
window->height = configure_notify->height;
|
||||
|
@ -808,41 +811,6 @@ weston_wm_window_activate(struct wl_listener *listener, void *data)
|
|||
|
||||
}
|
||||
|
||||
static void
|
||||
weston_wm_window_transform(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct weston_surface *surface = data;
|
||||
struct weston_wm_window *window = get_wm_window(surface);
|
||||
struct weston_wm *wm =
|
||||
container_of(listener, struct weston_wm, transform_listener);
|
||||
struct weston_view *view;
|
||||
struct weston_shell_interface *shell_interface =
|
||||
&wm->server->compositor->shell_interface;
|
||||
uint32_t mask, values[2];
|
||||
|
||||
if (!window || !wm || !window->shsurf)
|
||||
return;
|
||||
|
||||
if (!shell_interface->get_primary_view)
|
||||
return;
|
||||
|
||||
view = shell_interface->get_primary_view(shell_interface->shell,
|
||||
window->shsurf);
|
||||
|
||||
if (!view || !weston_view_is_mapped(view))
|
||||
return;
|
||||
|
||||
if (window->x != view->geometry.x ||
|
||||
window->y != view->geometry.y) {
|
||||
values[0] = view->geometry.x;
|
||||
values[1] = view->geometry.y;
|
||||
mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
|
||||
|
||||
xcb_configure_window(wm->conn, window->frame_id, mask, values);
|
||||
xcb_flush(wm->conn);
|
||||
}
|
||||
}
|
||||
|
||||
#define ICCCM_WITHDRAWN_STATE 0
|
||||
#define ICCCM_NORMAL_STATE 1
|
||||
#define ICCCM_ICONIC_STATE 3
|
||||
|
@ -1226,6 +1194,7 @@ weston_wm_window_create(struct weston_wm *wm,
|
|||
window->height = height;
|
||||
window->x = x;
|
||||
window->y = y;
|
||||
window->pos_dirty = false;
|
||||
|
||||
geometry_reply = xcb_get_geometry_reply(wm->conn, geometry_cookie, NULL);
|
||||
/* technically we should use XRender and check the visual format's
|
||||
|
@ -2316,9 +2285,6 @@ weston_wm_create(struct weston_xserver *wxs, int fd)
|
|||
wm->activate_listener.notify = weston_wm_window_activate;
|
||||
wl_signal_add(&wxs->compositor->activate_signal,
|
||||
&wm->activate_listener);
|
||||
wm->transform_listener.notify = weston_wm_window_transform;
|
||||
wl_signal_add(&wxs->compositor->transform_signal,
|
||||
&wm->transform_listener);
|
||||
wm->kill_listener.notify = weston_wm_kill_client;
|
||||
wl_signal_add(&wxs->compositor->kill_signal,
|
||||
&wm->kill_listener);
|
||||
|
@ -2347,7 +2313,6 @@ weston_wm_destroy(struct weston_wm *wm)
|
|||
wl_list_remove(&wm->selection_listener.link);
|
||||
wl_list_remove(&wm->activate_listener.link);
|
||||
wl_list_remove(&wm->kill_listener.link);
|
||||
wl_list_remove(&wm->transform_listener.link);
|
||||
wl_list_remove(&wm->create_surface_listener.link);
|
||||
|
||||
free(wm);
|
||||
|
@ -2438,8 +2403,35 @@ send_configure(struct weston_surface *surface, int32_t width, int32_t height)
|
|||
weston_wm_window_configure, window);
|
||||
}
|
||||
|
||||
static void
|
||||
send_position(struct weston_surface *surface, int32_t x, int32_t y)
|
||||
{
|
||||
struct weston_wm_window *window = get_wm_window(surface);
|
||||
struct weston_wm *wm;
|
||||
uint32_t mask, values[2];
|
||||
|
||||
if (!window || !window->wm)
|
||||
return;
|
||||
|
||||
wm = window->wm;
|
||||
/* We use pos_dirty to tell whether a configure message is in flight.
|
||||
* This is needed in case we send two configure events in a very
|
||||
* short time, since window->x/y is set in after a roundtrip, hence
|
||||
* we cannot just check if the current x and y are different. */
|
||||
if (window->x != x || window->y != y || window->pos_dirty) {
|
||||
window->pos_dirty = true;
|
||||
values[0] = x;
|
||||
values[1] = y;
|
||||
mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
|
||||
|
||||
xcb_configure_window(wm->conn, window->frame_id, mask, values);
|
||||
xcb_flush(wm->conn);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct weston_shell_client shell_client = {
|
||||
send_configure
|
||||
send_configure,
|
||||
send_position
|
||||
};
|
||||
|
||||
static int
|
||||
|
|
|
@ -70,7 +70,6 @@ struct weston_wm {
|
|||
xcb_colormap_t colormap;
|
||||
struct wl_listener create_surface_listener;
|
||||
struct wl_listener activate_listener;
|
||||
struct wl_listener transform_listener;
|
||||
struct wl_listener kill_listener;
|
||||
struct wl_list unpaired_window_list;
|
||||
|
||||
|
|
Loading…
Reference in a new issue