weston_surface_damage_below(surface);
weston_surface_assign_output(surface);
+
+ wl_signal_emit(&surface->compositor->transform_signal, surface);
}
WL_EXPORT void
ec->wl_display = display;
wl_signal_init(&ec->destroy_signal);
wl_signal_init(&ec->activate_signal);
+ wl_signal_init(&ec->transform_signal);
wl_signal_init(&ec->kill_signal);
wl_signal_init(&ec->idle_signal);
wl_signal_init(&ec->wake_signal);
uint32_t method,
uint32_t framerate,
struct weston_output *output);
+ void (*set_xwayland)(struct shell_surface *shsurf,
+ int x, int y, uint32_t flags);
int (*move)(struct shell_surface *shsurf, struct weston_seat *ws);
int (*resize)(struct shell_surface *shsurf,
struct weston_seat *ws, uint32_t edges);
struct weston_shell_interface shell_interface;
struct weston_config *config;
+ /* surface signals */
struct wl_signal activate_signal;
+ struct wl_signal transform_signal;
+
struct wl_signal kill_signal;
struct wl_signal idle_signal;
struct wl_signal wake_signal;
SHELL_SURFACE_TRANSIENT,
SHELL_SURFACE_FULLSCREEN,
SHELL_SURFACE_MAXIMIZED,
- SHELL_SURFACE_POPUP
+ SHELL_SURFACE_POPUP,
+ SHELL_SURFACE_XWAYLAND
};
struct ping_timer {
case SHELL_SURFACE_TOPLEVEL:
case SHELL_SURFACE_TRANSIENT:
case SHELL_SURFACE_POPUP:
+ case SHELL_SURFACE_XWAYLAND:
break;
}
}
break;
+ case SHELL_SURFACE_XWAYLAND:
+ weston_surface_set_position(surface, shsurf->transient.x,
+ shsurf->transient.y);
+ break;
+
default:
break;
}
set_fullscreen(shsurf, method, framerate, output);
}
+static void
+set_xwayland(struct shell_surface *shsurf, int x, int y, uint32_t flags)
+{
+ /* XXX: using the same fields for transient type */
+ shsurf->transient.x = x;
+ shsurf->transient.y = y;
+ shsurf->transient.flags = flags;
+ shsurf->next_type = SHELL_SURFACE_XWAYLAND;
+}
+
static const struct weston_pointer_grab_interface popup_grab_interface;
static void
case SHELL_SURFACE_FULLSCREEN:
case SHELL_SURFACE_NONE:
break;
+ case SHELL_SURFACE_XWAYLAND:
default:
ws = get_current_workspace(shell);
wl_list_insert(&ws->layer.surface_list, &surface->layer_link);
}
switch (surface_type) {
+ /* XXX: xwayland's using the same fields for transient type */
+ case SHELL_SURFACE_XWAYLAND:
case SHELL_SURFACE_TRANSIENT:
if (shsurf->transient.flags ==
WL_SHELL_SURFACE_TRANSIENT_INACTIVE)
{
struct shell_surface *shsurf = get_shell_surface(es);
struct desktop_shell *shell = shsurf->shell;
+ struct weston_compositor *compositor = shsurf->surface->compositor;
int type_changed = 0;
ec->shell_interface.set_toplevel = set_toplevel;
ec->shell_interface.set_transient = set_transient;
ec->shell_interface.set_fullscreen = set_fullscreen;
+ ec->shell_interface.set_xwayland = set_xwayland;
ec->shell_interface.move = surface_move;
ec->shell_interface.resize = surface_resize;
if (wm->focus_window)
weston_wm_window_schedule_repaint(wm->focus_window);
wm->focus_window = window;
- if (window)
- wm->focus_latest = window;
if (wm->focus_window)
weston_wm_window_schedule_repaint(wm->focus_window);
}
+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_output *output = surface->output;
+ uint32_t mask, values[2];
+ float sxf, syf;
+ int sx, sy;
+ static int old_sx = -1, old_sy = -1;
+
+ if (!window || !wm)
+ return;
+
+ if (!weston_surface_is_mapped(surface))
+ return;
+
+ weston_surface_to_global_float(surface, output->x, output->y,
+ &sxf, &syf);
+
+ sx = (int) sxf;
+ sy = (int) syf;
+
+ if (old_sx == sx && old_sy == sy)
+ return;
+
+ values[0] = sx;
+ values[1] = sy;
+ mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
+
+ xcb_configure_window(wm->conn, window->frame_id, mask, values);
+ xcb_flush(wm->conn);
+
+ old_sx = sx;
+ old_sy = sy;
+}
+
static int
our_resource(struct weston_wm *wm, uint32_t id)
{
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);
{
struct weston_shell_interface *shell_interface =
&wm->server->compositor->shell_interface;
- struct weston_wm_window *parent;
struct theme *t = window->wm->theme;
- int parent_id, x = 0, y = 0;
if (!shell_interface->create_shell_surface)
return;
0, NULL);
return;
} else if (!window->override_redirect) {
- /* ICCCM 4.1.1 */
shell_interface->set_toplevel(window->shsurf);
return;
+ } else {
+ shell_interface->set_xwayland(window->shsurf,
+ window->x + t->margin,
+ window->y + t->margin,
+ WL_SHELL_SURFACE_TRANSIENT_INACTIVE);
}
-
- /* not all non-toplevel has transient_for set. So we need this
- * workaround to guess a parent that will determine the relative
- * position of the transient surface */
- if (!window->transient_for)
- parent_id = wm->focus_latest->id;
- else
- parent_id = window->transient_for->id;
-
- parent = hash_table_lookup(wm->window_hash, parent_id);
-
- /* non-decorated and non-toplevel windows, e.g. sub-menus */
- if (!parent->decorate && parent->override_redirect) {
- x = parent->x + t->margin;
- y = parent->y + t->margin;
- }
-
- shell_interface->set_transient(window->shsurf, parent->surface,
- window->x + t->margin - x,
- window->y + t->margin - y,
- WL_SHELL_SURFACE_TRANSIENT_INACTIVE);
}
static void
struct weston_xserver *server;
xcb_window_t wm_window;
struct weston_wm_window *focus_window;
- struct weston_wm_window *focus_latest;
struct theme *theme;
xcb_cursor_t *cursors;
int last_cursor;
xcb_visualid_t visual_id;
xcb_colormap_t colormap;
struct wl_listener activate_listener;
+ struct wl_listener transform_listener;
struct wl_listener kill_listener;
xcb_window_t selection_window;