Skip to content

Commit ddc6979

Browse files
hideyukn88Hideyuki Nagase
andauthored
fix android emulator window is not movable when no frame (#17)
Co-authored-by: Hideyuki Nagase <hideyukn@ntdev.microsoft.com>
1 parent 40ea464 commit ddc6979

File tree

7 files changed

+122
-42
lines changed

7 files changed

+122
-42
lines changed

include/libweston-desktop/libweston-desktop.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ struct weston_desktop_api {
117117
*/
118118
void (*set_xwayland_position)(struct weston_desktop_surface *surface,
119119
int32_t x, int32_t y, void *user_data);
120+
/*
121+
* In contrast to above set_xwayland_position(), move_xwayland_position()
122+
* to be used to move window after mapped.
123+
*/
124+
void (*move_xwayland_position)(struct weston_desktop_surface *surface,
125+
int32_t x, int32_t y, void *user_data);
120126
};
121127

122128
void

libweston-desktop/internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ weston_desktop_api_set_xwayland_position(struct weston_desktop *desktop,
9191
struct weston_desktop_surface *surface,
9292
int32_t x, int32_t y);
9393

94+
void
95+
weston_desktop_api_move_xwayland_position(struct weston_desktop *desktop,
96+
struct weston_desktop_surface *surface,
97+
int32_t x, int32_t y);
98+
9499
struct weston_desktop_seat *
95100
weston_desktop_seat_from_seat(struct weston_seat *wseat);
96101

libweston-desktop/libweston-desktop.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,13 @@ weston_desktop_api_set_xwayland_position(struct weston_desktop *desktop,
262262
desktop->api.set_xwayland_position(surface, x, y,
263263
desktop->user_data);
264264
}
265+
266+
void
267+
weston_desktop_api_move_xwayland_position(struct weston_desktop *desktop,
268+
struct weston_desktop_surface *surface,
269+
int32_t x, int32_t y)
270+
{
271+
if (desktop->api.move_xwayland_position != NULL)
272+
desktop->api.move_xwayland_position(surface, x, y,
273+
desktop->user_data);
274+
}

libweston-desktop/xwayland.c

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,29 @@ set_xwayland(struct weston_desktop_xwayland_surface *surface, int x, int y)
328328
weston_view_set_position(surface->view, x, y);
329329
}
330330

331+
static void
332+
move_position(struct weston_desktop_xwayland_surface *surface, int x, int y)
333+
{
334+
if (surface->state == XWAYLAND) {
335+
/* For XWAYLAND surface, here directly set view position,
336+
just like set_xwayland() when view is associated. */
337+
if (surface->view)
338+
weston_view_set_position(surface->view, x, y);
339+
} else if (surface->state == TOPLEVEL) {
340+
weston_desktop_api_move_xwayland_position(surface->desktop,
341+
surface->surface, x, y);
342+
}
343+
#ifdef WM_DEBUG
344+
weston_log("%s: %s window (%p) move to (%d,%d)\n",
345+
__func__,
346+
(surface->state == XWAYLAND) ? "XWAYLAND" : \
347+
(surface->state == TOPLEVEL) ? "TOPLEVEL" : \
348+
(surface->state == MAXIMIZED) ? "MAXIMIZED" : \
349+
(surface->state == FULLSCREEN) ? "FULLSCREEN" : "UNKNOWN",
350+
surface, x, y);
351+
#endif
352+
}
353+
331354
static int
332355
move(struct weston_desktop_xwayland_surface *surface,
333356
struct weston_pointer *pointer)
@@ -375,29 +398,6 @@ set_window_geometry(struct weston_desktop_xwayland_surface *surface,
375398
}
376399
}
377400

378-
static void
379-
set_position(struct weston_desktop_xwayland_surface *surface,
380-
int x, int y, int width, int height)
381-
{
382-
if (surface->state == XWAYLAND) {
383-
/* For XWAYLAND surface, here directly set view position,
384-
just like set_xwayland() when view is associated. */
385-
if (surface->view)
386-
weston_view_set_position(surface->view, x, y);
387-
} else {
388-
/* TODO what to do these? need a way to move shell surface! */
389-
}
390-
#ifdef WM_DEBUG
391-
weston_log("%s: %s window (%p) move to (%d,%d)\n",
392-
__func__,
393-
(surface->state == XWAYLAND) ? "XWAYLAND" : \
394-
(surface->state == TOPLEVEL) ? "TOPLEVEL" : \
395-
(surface->state == MAXIMIZED) ? "MAXIMIZED" : \
396-
(surface->state == FULLSCREEN) ? "FULLSCREEN" : "UNKNOWN",
397-
surface, x, y);
398-
#endif
399-
}
400-
401401
static void
402402
set_maximized(struct weston_desktop_xwayland_surface *surface)
403403
{
@@ -436,7 +436,7 @@ static const struct weston_desktop_xwayland_interface weston_desktop_xwayland_in
436436
.set_transient = set_transient,
437437
.set_fullscreen = set_fullscreen,
438438
.set_xwayland = set_xwayland,
439-
.set_position = set_position,
439+
.move_position = move_position,
440440
.move = move,
441441
.resize = resize,
442442
.set_title = set_title,

rdprail-shell/shell.c

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2138,8 +2138,8 @@ set_position_from_xwayland(struct shell_surface *shsurf)
21382138
/* Use xwayland position as this is the X app's origin of client area */
21392139
if (shsurf->xwayland.x >= area.x &&
21402140
shsurf->xwayland.y >= area.y &&
2141-
shsurf->xwayland.x <= (int32_t)(area.x + area.width - (area.width / 10)) &&
2142-
shsurf->xwayland.y <= (int32_t)(area.y + area.width - (area.width / 10))) {
2141+
shsurf->xwayland.x < (int32_t)(area.x + area.width - (area.width / 10)) &&
2142+
shsurf->xwayland.y < (int32_t)(area.y + area.height - (area.height / 10))) {
21432143

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

@@ -2808,6 +2808,41 @@ desktop_surface_set_xwayland_position(struct weston_desktop_surface *surface,
28082808
shsurf->xwayland.is_set = true;
28092809
}
28102810

2811+
static void
2812+
desktop_surface_move_xwayland_position(struct weston_desktop_surface *desktop_surface,
2813+
int32_t x, int32_t y, void *shell_)
2814+
{
2815+
struct weston_surface *surface =
2816+
weston_desktop_surface_get_surface(desktop_surface);
2817+
struct shell_surface *shsurf =
2818+
weston_desktop_surface_get_user_data(desktop_surface);
2819+
struct desktop_shell *shell = shsurf->shell;
2820+
const struct weston_xwayland_surface_api *api;
2821+
2822+
assert(shell == shell_);
2823+
2824+
api = shell->xwayland_surface_api;
2825+
if (!api) {
2826+
api = weston_xwayland_surface_get_api(shell->compositor);
2827+
shell->xwayland_surface_api = api;
2828+
}
2829+
if (api && api->is_xwayland_surface(surface)) {
2830+
/* TODO: Make sure the position given from xwayland is a part of workarea,
2831+
But this is not simple, for example, app can have accompanying
2832+
window which move along with other main window, in such case,
2833+
often, it's totally fine the accompanying goes out of workarea. */
2834+
2835+
weston_view_set_position(shsurf->view, x, y);
2836+
weston_compositor_schedule_repaint(shell->compositor);
2837+
2838+
shell_rdp_debug_verbose(shell, "%s: surface:%p, position (%d,%d)\n",
2839+
__func__, surface, x, y);
2840+
} else {
2841+
shell_rdp_debug_error(shell, "%s: surface:%p is not from xwayland\n",
2842+
__func__, surface);
2843+
}
2844+
}
2845+
28112846
static const struct weston_desktop_api shell_desktop_api = {
28122847
.struct_size = sizeof(struct weston_desktop_api),
28132848
.surface_added = desktop_surface_added,
@@ -2822,6 +2857,7 @@ static const struct weston_desktop_api shell_desktop_api = {
28222857
.ping_timeout = desktop_surface_ping_timeout,
28232858
.pong = desktop_surface_pong,
28242859
.set_xwayland_position = desktop_surface_set_xwayland_position,
2860+
.move_xwayland_position = desktop_surface_move_xwayland_position,
28252861
.set_window_icon = desktop_surface_set_window_icon,
28262862
};
28272863

xwayland/window-manager.c

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ struct weston_wm_window {
157157
int x;
158158
int y;
159159
bool pos_dirty;
160+
int frame_x;
161+
int frame_y;
160162
int map_request_x;
161163
int map_request_y;
162164
struct weston_output_weak_ref legacy_fullscreen_output;
@@ -757,6 +759,7 @@ weston_wm_window_send_configure_notify(struct weston_wm_window *window)
757759
{
758760
xcb_configure_notify_event_t configure_notify;
759761
struct weston_wm *wm = window->wm;
762+
bool is_our_resource = our_resource(wm, window->id);
760763
int x, y;
761764

762765
weston_wm_window_get_child_position(window, &x, &y);
@@ -776,13 +779,18 @@ weston_wm_window_send_configure_notify(struct weston_wm_window *window)
776779
xcb_send_event(wm->conn, 0, window->id,
777780
XCB_EVENT_MASK_STRUCTURE_NOTIFY,
778781
(char *) &configure_notify);
782+
783+
wm_printf(wm, "XWM: send_configure_notify (window %d) %d,%d @ %dx%d%s\n",
784+
window->id, x, y, window->width, window->height,
785+
is_our_resource ? ", ours" : "");
779786
}
780787

781788
static void
782-
weston_wm_window_send_event_configure_notify_window_position(struct weston_wm_window *window, int x, int y)
789+
weston_wm_window_send_event_configure_notify_with_position(struct weston_wm_window *window, int x, int y)
783790
{
784791
xcb_configure_notify_event_t configure_notify;
785792
struct weston_wm *wm = window->wm;
793+
bool is_our_resource = our_resource(wm, window->id);
786794

787795
configure_notify.response_type = XCB_CONFIGURE_NOTIFY;
788796
configure_notify.pad0 = 0;
@@ -800,6 +808,10 @@ weston_wm_window_send_event_configure_notify_window_position(struct weston_wm_wi
800808
xcb_send_event(wm->conn, 0, window->id,
801809
XCB_EVENT_MASK_STRUCTURE_NOTIFY,
802810
(char *) &configure_notify);
811+
812+
wm_printf(wm, "XWM: send_event_configure_notify_window_position (window %d) %d,%d @ %dx%d%s\n",
813+
window->id, x, y, window->width, window->height,
814+
is_our_resource ? ", ours" : "");
803815
}
804816

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

1021-
window->x = configure_notify->x;
1022-
window->y = configure_notify->y;
1033+
if (window->override_redirect || is_our_resource) {
1034+
/* override or frame */
1035+
window->frame_x = configure_notify->x;
1036+
window->frame_y = configure_notify->y;
1037+
}
1038+
if (window->override_redirect || !is_our_resource) {
1039+
/* override or not frame */
1040+
window->x = configure_notify->x;
1041+
window->y = configure_notify->y;
1042+
}
10231043
window->pos_dirty = false;
10241044

10251045
if (window->override_redirect) {
@@ -1037,9 +1057,8 @@ weston_wm_handle_configure_notify(struct weston_wm *wm, xcb_generic_event_t *eve
10371057
window->x, window->y);
10381058
} else if (is_our_resource) {
10391059
if (window->shsurf)
1040-
xwayland_api->set_position(window->shsurf,
1041-
window->x, window->y,
1042-
window->width, window->height);
1060+
xwayland_api->move_position(window->shsurf,
1061+
window->frame_x, window->frame_y);
10431062
}
10441063
}
10451064

@@ -1755,6 +1774,8 @@ weston_wm_window_create(struct weston_wm *wm,
17551774
window->x = x;
17561775
window->y = y;
17571776
window->pos_dirty = false;
1777+
window->frame_x = INT_MIN;
1778+
window->frame_y = INT_MIN;
17581779
window->map_request_x = INT_MIN; /* out of range for valid positions */
17591780
window->map_request_y = INT_MIN; /* out of range for valid positions */
17601781
weston_output_weak_ref_init(&window->legacy_fullscreen_output);
@@ -3068,24 +3089,26 @@ send_position(struct weston_surface *surface, int32_t x, int32_t y)
30683089
{
30693090
struct weston_wm_window *window = get_wm_window(surface);
30703091
struct weston_wm *wm;
3071-
uint32_t values[2];
3072-
uint16_t mask;
30733092
int dx, dy;
30743093

30753094
if (!window || !window->wm)
30763095
return;
30773096

30783097
wm = window->wm;
3098+
3099+
wm_printf(wm, "XWM: send_position (window %d) input %d,%d frame %d,%d window %d,%d%s\n",
3100+
window->id, x, y,
3101+
window->frame_x, window->frame_y,
3102+
window->x, window->y,
3103+
window->override_redirect ? ", override" : "");
3104+
30793105
/* We use pos_dirty to tell whether a configure message is in flight.
30803106
* This is needed in case we send two configure events in a very
30813107
* short time, since window->x/y is set in after a roundtrip, hence
30823108
* we cannot just check if the current x and y are different. */
3083-
if (window->x != x || window->y != y || window->pos_dirty) {
3109+
if (window->frame_x != x || window->frame_y != y || window->pos_dirty) {
30843110
window->pos_dirty = true;
3085-
values[0] = x;
3086-
values[1] = y;
3087-
mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
3088-
weston_wm_configure_window(wm, window->frame_id, mask, values);
3111+
weston_wm_window_configure_frame_with_position(window, x, y);
30893112

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

31023125
xcb_flush(wm->conn);
31033126
}

xwayland/xwayland-internal-interface.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ struct weston_desktop_xwayland_interface {
4848
struct weston_output *output);
4949
void (*set_xwayland)(struct weston_desktop_xwayland_surface *shsurf,
5050
int x, int y);
51-
void (*set_position)(struct weston_desktop_xwayland_surface *shsurf,
52-
int x, int y, int width, int height);
51+
void (*move_position)(struct weston_desktop_xwayland_surface *shsurf,
52+
int x, int y);
5353
int (*move)(struct weston_desktop_xwayland_surface *shsurf,
5454
struct weston_pointer *pointer);
5555
int (*resize)(struct weston_desktop_xwayland_surface *shsurf,

0 commit comments

Comments
 (0)