Skip to content

Commit

Permalink
fix android emulator window is not movable when no frame (#17)
Browse files Browse the repository at this point in the history
Co-authored-by: Hideyuki Nagase <hideyukn@ntdev.microsoft.com>
  • Loading branch information
hideyukn88 and Hideyuki Nagase authored May 25, 2021
1 parent 40ea464 commit ddc6979
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 42 deletions.
6 changes: 6 additions & 0 deletions include/libweston-desktop/libweston-desktop.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ struct weston_desktop_api {
*/
void (*set_xwayland_position)(struct weston_desktop_surface *surface,
int32_t x, int32_t y, void *user_data);
/*
* In contrast to above set_xwayland_position(), move_xwayland_position()
* to be used to move window after mapped.
*/
void (*move_xwayland_position)(struct weston_desktop_surface *surface,
int32_t x, int32_t y, void *user_data);
};

void
Expand Down
5 changes: 5 additions & 0 deletions libweston-desktop/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ weston_desktop_api_set_xwayland_position(struct weston_desktop *desktop,
struct weston_desktop_surface *surface,
int32_t x, int32_t y);

void
weston_desktop_api_move_xwayland_position(struct weston_desktop *desktop,
struct weston_desktop_surface *surface,
int32_t x, int32_t y);

struct weston_desktop_seat *
weston_desktop_seat_from_seat(struct weston_seat *wseat);

Expand Down
10 changes: 10 additions & 0 deletions libweston-desktop/libweston-desktop.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,13 @@ weston_desktop_api_set_xwayland_position(struct weston_desktop *desktop,
desktop->api.set_xwayland_position(surface, x, y,
desktop->user_data);
}

void
weston_desktop_api_move_xwayland_position(struct weston_desktop *desktop,
struct weston_desktop_surface *surface,
int32_t x, int32_t y)
{
if (desktop->api.move_xwayland_position != NULL)
desktop->api.move_xwayland_position(surface, x, y,
desktop->user_data);
}
48 changes: 24 additions & 24 deletions libweston-desktop/xwayland.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,29 @@ set_xwayland(struct weston_desktop_xwayland_surface *surface, int x, int y)
weston_view_set_position(surface->view, x, y);
}

static void
move_position(struct weston_desktop_xwayland_surface *surface, int x, int y)
{
if (surface->state == XWAYLAND) {
/* For XWAYLAND surface, here directly set view position,
just like set_xwayland() when view is associated. */
if (surface->view)
weston_view_set_position(surface->view, x, y);
} else if (surface->state == TOPLEVEL) {
weston_desktop_api_move_xwayland_position(surface->desktop,
surface->surface, x, y);
}
#ifdef WM_DEBUG
weston_log("%s: %s window (%p) move to (%d,%d)\n",
__func__,
(surface->state == XWAYLAND) ? "XWAYLAND" : \
(surface->state == TOPLEVEL) ? "TOPLEVEL" : \
(surface->state == MAXIMIZED) ? "MAXIMIZED" : \
(surface->state == FULLSCREEN) ? "FULLSCREEN" : "UNKNOWN",
surface, x, y);
#endif
}

static int
move(struct weston_desktop_xwayland_surface *surface,
struct weston_pointer *pointer)
Expand Down Expand Up @@ -375,29 +398,6 @@ set_window_geometry(struct weston_desktop_xwayland_surface *surface,
}
}

static void
set_position(struct weston_desktop_xwayland_surface *surface,
int x, int y, int width, int height)
{
if (surface->state == XWAYLAND) {
/* For XWAYLAND surface, here directly set view position,
just like set_xwayland() when view is associated. */
if (surface->view)
weston_view_set_position(surface->view, x, y);
} else {
/* TODO what to do these? need a way to move shell surface! */
}
#ifdef WM_DEBUG
weston_log("%s: %s window (%p) move to (%d,%d)\n",
__func__,
(surface->state == XWAYLAND) ? "XWAYLAND" : \
(surface->state == TOPLEVEL) ? "TOPLEVEL" : \
(surface->state == MAXIMIZED) ? "MAXIMIZED" : \
(surface->state == FULLSCREEN) ? "FULLSCREEN" : "UNKNOWN",
surface, x, y);
#endif
}

static void
set_maximized(struct weston_desktop_xwayland_surface *surface)
{
Expand Down Expand Up @@ -436,7 +436,7 @@ static const struct weston_desktop_xwayland_interface weston_desktop_xwayland_in
.set_transient = set_transient,
.set_fullscreen = set_fullscreen,
.set_xwayland = set_xwayland,
.set_position = set_position,
.move_position = move_position,
.move = move,
.resize = resize,
.set_title = set_title,
Expand Down
40 changes: 38 additions & 2 deletions rdprail-shell/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -2138,8 +2138,8 @@ set_position_from_xwayland(struct shell_surface *shsurf)
/* Use xwayland position as this is the X app's origin of client area */
if (shsurf->xwayland.x >= area.x &&
shsurf->xwayland.y >= area.y &&
shsurf->xwayland.x <= (int32_t)(area.x + area.width - (area.width / 10)) &&
shsurf->xwayland.y <= (int32_t)(area.y + area.width - (area.width / 10))) {
shsurf->xwayland.x < (int32_t)(area.x + area.width - (area.width / 10)) &&
shsurf->xwayland.y < (int32_t)(area.y + area.height - (area.height / 10))) {

weston_view_set_position(shsurf->view, x, y);

Expand Down Expand Up @@ -2808,6 +2808,41 @@ desktop_surface_set_xwayland_position(struct weston_desktop_surface *surface,
shsurf->xwayland.is_set = true;
}

static void
desktop_surface_move_xwayland_position(struct weston_desktop_surface *desktop_surface,
int32_t x, int32_t y, void *shell_)
{
struct weston_surface *surface =
weston_desktop_surface_get_surface(desktop_surface);
struct shell_surface *shsurf =
weston_desktop_surface_get_user_data(desktop_surface);
struct desktop_shell *shell = shsurf->shell;
const struct weston_xwayland_surface_api *api;

assert(shell == shell_);

api = shell->xwayland_surface_api;
if (!api) {
api = weston_xwayland_surface_get_api(shell->compositor);
shell->xwayland_surface_api = api;
}
if (api && api->is_xwayland_surface(surface)) {
/* TODO: Make sure the position given from xwayland is a part of workarea,
But this is not simple, for example, app can have accompanying
window which move along with other main window, in such case,
often, it's totally fine the accompanying goes out of workarea. */

weston_view_set_position(shsurf->view, x, y);
weston_compositor_schedule_repaint(shell->compositor);

shell_rdp_debug_verbose(shell, "%s: surface:%p, position (%d,%d)\n",
__func__, surface, x, y);
} else {
shell_rdp_debug_error(shell, "%s: surface:%p is not from xwayland\n",
__func__, surface);
}
}

static const struct weston_desktop_api shell_desktop_api = {
.struct_size = sizeof(struct weston_desktop_api),
.surface_added = desktop_surface_added,
Expand All @@ -2822,6 +2857,7 @@ static const struct weston_desktop_api shell_desktop_api = {
.ping_timeout = desktop_surface_ping_timeout,
.pong = desktop_surface_pong,
.set_xwayland_position = desktop_surface_set_xwayland_position,
.move_xwayland_position = desktop_surface_move_xwayland_position,
.set_window_icon = desktop_surface_set_window_icon,
};

Expand Down
51 changes: 37 additions & 14 deletions xwayland/window-manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ struct weston_wm_window {
int x;
int y;
bool pos_dirty;
int frame_x;
int frame_y;
int map_request_x;
int map_request_y;
struct weston_output_weak_ref legacy_fullscreen_output;
Expand Down Expand Up @@ -757,6 +759,7 @@ weston_wm_window_send_configure_notify(struct weston_wm_window *window)
{
xcb_configure_notify_event_t configure_notify;
struct weston_wm *wm = window->wm;
bool is_our_resource = our_resource(wm, window->id);
int x, y;

weston_wm_window_get_child_position(window, &x, &y);
Expand All @@ -776,13 +779,18 @@ weston_wm_window_send_configure_notify(struct weston_wm_window *window)
xcb_send_event(wm->conn, 0, window->id,
XCB_EVENT_MASK_STRUCTURE_NOTIFY,
(char *) &configure_notify);

wm_printf(wm, "XWM: send_configure_notify (window %d) %d,%d @ %dx%d%s\n",
window->id, x, y, window->width, window->height,
is_our_resource ? ", ours" : "");
}

static void
weston_wm_window_send_event_configure_notify_window_position(struct weston_wm_window *window, int x, int y)
weston_wm_window_send_event_configure_notify_with_position(struct weston_wm_window *window, int x, int y)
{
xcb_configure_notify_event_t configure_notify;
struct weston_wm *wm = window->wm;
bool is_our_resource = our_resource(wm, window->id);

configure_notify.response_type = XCB_CONFIGURE_NOTIFY;
configure_notify.pad0 = 0;
Expand All @@ -800,6 +808,10 @@ weston_wm_window_send_event_configure_notify_window_position(struct weston_wm_wi
xcb_send_event(wm->conn, 0, window->id,
XCB_EVENT_MASK_STRUCTURE_NOTIFY,
(char *) &configure_notify);

wm_printf(wm, "XWM: send_event_configure_notify_window_position (window %d) %d,%d @ %dx%d%s\n",
window->id, x, y, window->width, window->height,
is_our_resource ? ", ours" : "");
}

static void
Expand Down Expand Up @@ -1018,8 +1030,16 @@ weston_wm_handle_configure_notify(struct weston_wm *wm, xcb_generic_event_t *eve
if (!wm_lookup_window(wm, configure_notify->window, &window))
return;

window->x = configure_notify->x;
window->y = configure_notify->y;
if (window->override_redirect || is_our_resource) {
/* override or frame */
window->frame_x = configure_notify->x;
window->frame_y = configure_notify->y;
}
if (window->override_redirect || !is_our_resource) {
/* override or not frame */
window->x = configure_notify->x;
window->y = configure_notify->y;
}
window->pos_dirty = false;

if (window->override_redirect) {
Expand All @@ -1037,9 +1057,8 @@ weston_wm_handle_configure_notify(struct weston_wm *wm, xcb_generic_event_t *eve
window->x, window->y);
} else if (is_our_resource) {
if (window->shsurf)
xwayland_api->set_position(window->shsurf,
window->x, window->y,
window->width, window->height);
xwayland_api->move_position(window->shsurf,
window->frame_x, window->frame_y);
}
}

Expand Down Expand Up @@ -1755,6 +1774,8 @@ weston_wm_window_create(struct weston_wm *wm,
window->x = x;
window->y = y;
window->pos_dirty = false;
window->frame_x = INT_MIN;
window->frame_y = INT_MIN;
window->map_request_x = INT_MIN; /* out of range for valid positions */
window->map_request_y = INT_MIN; /* out of range for valid positions */
weston_output_weak_ref_init(&window->legacy_fullscreen_output);
Expand Down Expand Up @@ -3068,24 +3089,26 @@ 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 values[2];
uint16_t mask;
int dx, dy;

if (!window || !window->wm)
return;

wm = window->wm;

wm_printf(wm, "XWM: send_position (window %d) input %d,%d frame %d,%d window %d,%d%s\n",
window->id, x, y,
window->frame_x, window->frame_y,
window->x, window->y,
window->override_redirect ? ", override" : "");

/* 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) {
if (window->frame_x != x || window->frame_y != y || window->pos_dirty) {
window->pos_dirty = true;
values[0] = x;
values[1] = y;
mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
weston_wm_configure_window(wm, window->frame_id, mask, values);
weston_wm_window_configure_frame_with_position(window, x, y);

// !!! need further investigation !!!
/* Xwayland reparents app's window with our own frame window
Expand All @@ -3097,7 +3120,7 @@ send_position(struct weston_surface *surface, int32_t x, int32_t y)
event to let application knows actual app's window position (rather
than offset from parent/frame window */
weston_wm_window_get_child_position(window, &dx, &dy);
weston_wm_window_send_event_configure_notify_window_position(window, x + dx, y + dy);
weston_wm_window_send_event_configure_notify_with_position(window, x + dx, y + dy);

xcb_flush(wm->conn);
}
Expand Down
4 changes: 2 additions & 2 deletions xwayland/xwayland-internal-interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ struct weston_desktop_xwayland_interface {
struct weston_output *output);
void (*set_xwayland)(struct weston_desktop_xwayland_surface *shsurf,
int x, int y);
void (*set_position)(struct weston_desktop_xwayland_surface *shsurf,
int x, int y, int width, int height);
void (*move_position)(struct weston_desktop_xwayland_surface *shsurf,
int x, int y);
int (*move)(struct weston_desktop_xwayland_surface *shsurf,
struct weston_pointer *pointer);
int (*resize)(struct weston_desktop_xwayland_surface *shsurf,
Expand Down

0 comments on commit ddc6979

Please sign in to comment.