xwm: support maximizing xwayland windows
This patch adds the maximize button to the window frame for the windows which set the MWM_DECOR_MAXIMIZE hint, and it wires it with the shell via a new method in weston_shell_interface. Additionally, it also listens for the wm hints coming from the client, but it doesn't support maximizing a window only vertically or horizontally. The window will be maximized only when both directions are maximized. Reviewed-by: Daniel Stone <daniels@collabora.com> Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
This commit is contained in:
committed by
Bryce Harrington
parent
8aeeac827f
commit
6b4b24155f
+46
-26
@@ -3000,6 +3000,51 @@ shell_interface_set_fullscreen(struct shell_surface *shsurf,
|
|||||||
set_fullscreen(shsurf, method, framerate, output);
|
set_fullscreen(shsurf, method, framerate, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct weston_output *
|
||||||
|
get_focused_output(struct weston_compositor *compositor)
|
||||||
|
{
|
||||||
|
struct weston_seat *seat;
|
||||||
|
struct weston_output *output = NULL;
|
||||||
|
|
||||||
|
wl_list_for_each(seat, &compositor->seat_list, link) {
|
||||||
|
/* Priority has touch focus, then pointer and
|
||||||
|
* then keyboard focus. We should probably have
|
||||||
|
* three for loops and check frist for touch,
|
||||||
|
* then for pointer, etc. but unless somebody has some
|
||||||
|
* objections, I think this is sufficient. */
|
||||||
|
if (seat->touch && seat->touch->focus)
|
||||||
|
output = seat->touch->focus->output;
|
||||||
|
else if (seat->pointer && seat->pointer->focus)
|
||||||
|
output = seat->pointer->focus->output;
|
||||||
|
else if (seat->keyboard && seat->keyboard->focus)
|
||||||
|
output = seat->keyboard->focus->output;
|
||||||
|
|
||||||
|
if (output)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_interface_set_maximized(struct shell_surface *shsurf)
|
||||||
|
{
|
||||||
|
struct weston_output *output;
|
||||||
|
|
||||||
|
surface_clear_next_states(shsurf);
|
||||||
|
shsurf->next_state.maximized = true;
|
||||||
|
shsurf->state_changed = true;
|
||||||
|
shsurf->type = SHELL_SURFACE_TOPLEVEL;
|
||||||
|
|
||||||
|
if (!weston_surface_is_mapped(shsurf->surface))
|
||||||
|
output = get_focused_output(shsurf->surface->compositor);
|
||||||
|
else
|
||||||
|
output = shsurf->surface->output;
|
||||||
|
|
||||||
|
shell_surface_set_output(shsurf, output);
|
||||||
|
send_configure_for_surface(shsurf);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
shell_interface_move(struct shell_surface *shsurf, struct weston_seat *ws)
|
shell_interface_move(struct shell_surface *shsurf, struct weston_seat *ws)
|
||||||
{
|
{
|
||||||
@@ -3605,32 +3650,6 @@ get_primary_view(void *shell, struct shell_surface *shsurf)
|
|||||||
return shsurf->view;
|
return shsurf->view;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct weston_output *
|
|
||||||
get_focused_output(struct weston_compositor *compositor)
|
|
||||||
{
|
|
||||||
struct weston_seat *seat;
|
|
||||||
struct weston_output *output = NULL;
|
|
||||||
|
|
||||||
wl_list_for_each(seat, &compositor->seat_list, link) {
|
|
||||||
/* Priority has touch focus, then pointer and
|
|
||||||
* then keyboard focus. We should probably have
|
|
||||||
* three for loops and check frist for touch,
|
|
||||||
* then for pointer, etc. but unless somebody has some
|
|
||||||
* objections, I think this is sufficient. */
|
|
||||||
if (seat->touch && seat->touch->focus)
|
|
||||||
output = seat->touch->focus->output;
|
|
||||||
else if (seat->pointer && seat->pointer->focus)
|
|
||||||
output = seat->pointer->focus->output;
|
|
||||||
else if (seat->keyboard && seat->keyboard->focus)
|
|
||||||
output = seat->keyboard->focus->output;
|
|
||||||
|
|
||||||
if (output)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
shell_get_shell_surface(struct wl_client *client,
|
shell_get_shell_surface(struct wl_client *client,
|
||||||
struct wl_resource *resource,
|
struct wl_resource *resource,
|
||||||
@@ -6633,6 +6652,7 @@ module_init(struct weston_compositor *ec,
|
|||||||
ec->shell_interface.resize = surface_resize;
|
ec->shell_interface.resize = surface_resize;
|
||||||
ec->shell_interface.set_title = set_title;
|
ec->shell_interface.set_title = set_title;
|
||||||
ec->shell_interface.set_window_geometry = set_window_geometry;
|
ec->shell_interface.set_window_geometry = set_window_geometry;
|
||||||
|
ec->shell_interface.set_maximized = shell_interface_set_maximized;
|
||||||
|
|
||||||
weston_layer_init(&shell->fullscreen_layer, &ec->cursor_layer.link);
|
weston_layer_init(&shell->fullscreen_layer, &ec->cursor_layer.link);
|
||||||
weston_layer_init(&shell->panel_layer, &shell->fullscreen_layer.link);
|
weston_layer_init(&shell->panel_layer, &shell->fullscreen_layer.link);
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ struct weston_shell_interface {
|
|||||||
void (*set_window_geometry)(struct shell_surface *shsurf,
|
void (*set_window_geometry)(struct shell_surface *shsurf,
|
||||||
int32_t x, int32_t y,
|
int32_t x, int32_t y,
|
||||||
int32_t width, int32_t height);
|
int32_t width, int32_t height);
|
||||||
|
void (*set_maximized)(struct shell_surface *shsurf);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct weston_animation {
|
struct weston_animation {
|
||||||
|
|||||||
+79
-12
@@ -144,6 +144,8 @@ struct weston_wm_window {
|
|||||||
int fullscreen;
|
int fullscreen;
|
||||||
int has_alpha;
|
int has_alpha;
|
||||||
int delete_window;
|
int delete_window;
|
||||||
|
int maximized_vert;
|
||||||
|
int maximized_horz;
|
||||||
struct wm_size_hints size_hints;
|
struct wm_size_hints size_hints;
|
||||||
struct motif_wm_hints motif_hints;
|
struct motif_wm_hints motif_hints;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
@@ -472,6 +474,10 @@ weston_wm_window_read_properties(struct weston_wm_window *window)
|
|||||||
for (i = 0; i < reply->value_len; i++)
|
for (i = 0; i < reply->value_len; i++)
|
||||||
if (atom[i] == wm->atom.net_wm_state_fullscreen)
|
if (atom[i] == wm->atom.net_wm_state_fullscreen)
|
||||||
window->fullscreen = 1;
|
window->fullscreen = 1;
|
||||||
|
if (atom[i] == wm->atom.net_wm_state_maximized_vert)
|
||||||
|
window->maximized_vert = 1;
|
||||||
|
if (atom[i] == wm->atom.net_wm_state_maximized_horz)
|
||||||
|
window->maximized_horz = 1;
|
||||||
break;
|
break;
|
||||||
case TYPE_MOTIF_WM_HINTS:
|
case TYPE_MOTIF_WM_HINTS:
|
||||||
memcpy(&window->motif_hints,
|
memcpy(&window->motif_hints,
|
||||||
@@ -479,7 +485,7 @@ weston_wm_window_read_properties(struct weston_wm_window *window)
|
|||||||
sizeof window->motif_hints);
|
sizeof window->motif_hints);
|
||||||
if (window->motif_hints.flags & MWM_HINTS_DECORATIONS)
|
if (window->motif_hints.flags & MWM_HINTS_DECORATIONS)
|
||||||
window->decorate =
|
window->decorate =
|
||||||
window->motif_hints.decorations > 0;
|
window->motif_hints.decorations;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -789,12 +795,16 @@ static void
|
|||||||
weston_wm_window_set_net_wm_state(struct weston_wm_window *window)
|
weston_wm_window_set_net_wm_state(struct weston_wm_window *window)
|
||||||
{
|
{
|
||||||
struct weston_wm *wm = window->wm;
|
struct weston_wm *wm = window->wm;
|
||||||
uint32_t property[1];
|
uint32_t property[3];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
if (window->fullscreen)
|
if (window->fullscreen)
|
||||||
property[i++] = wm->atom.net_wm_state_fullscreen;
|
property[i++] = wm->atom.net_wm_state_fullscreen;
|
||||||
|
if (window->maximized_vert)
|
||||||
|
property[i++] = wm->atom.net_wm_state_maximized_vert;
|
||||||
|
if (window->maximized_horz)
|
||||||
|
property[i++] = wm->atom.net_wm_state_maximized_horz;
|
||||||
|
|
||||||
xcb_change_property(wm->conn,
|
xcb_change_property(wm->conn,
|
||||||
XCB_PROP_MODE_REPLACE,
|
XCB_PROP_MODE_REPLACE,
|
||||||
@@ -811,10 +821,14 @@ weston_wm_window_create_frame(struct weston_wm_window *window)
|
|||||||
struct weston_wm *wm = window->wm;
|
struct weston_wm *wm = window->wm;
|
||||||
uint32_t values[3];
|
uint32_t values[3];
|
||||||
int x, y, width, height;
|
int x, y, width, height;
|
||||||
|
int buttons = FRAME_BUTTON_CLOSE;
|
||||||
|
|
||||||
|
if (window->decorate & MWM_DECOR_MAXIMIZE)
|
||||||
|
buttons |= FRAME_BUTTON_MAXIMIZE;
|
||||||
|
|
||||||
window->frame = frame_create(window->wm->theme,
|
window->frame = frame_create(window->wm->theme,
|
||||||
window->width, window->height,
|
window->width, window->height,
|
||||||
FRAME_BUTTON_CLOSE, window->name);
|
buttons, window->name);
|
||||||
frame_resize_inside(window->frame, window->width, window->height);
|
frame_resize_inside(window->frame, window->width, window->height);
|
||||||
|
|
||||||
weston_wm_window_get_frame_size(window, &width, &height);
|
weston_wm_window_get_frame_size(window, &width, &height);
|
||||||
@@ -1331,6 +1345,28 @@ update_state(int action, int *state)
|
|||||||
static void
|
static void
|
||||||
weston_wm_window_configure(void *data);
|
weston_wm_window_configure(void *data);
|
||||||
|
|
||||||
|
static void
|
||||||
|
weston_wm_window_set_toplevel(struct weston_wm_window *window)
|
||||||
|
{
|
||||||
|
struct weston_shell_interface *shell_interface =
|
||||||
|
&window->wm->server->compositor->shell_interface;
|
||||||
|
|
||||||
|
shell_interface->set_toplevel(window->shsurf);
|
||||||
|
window->width = window->saved_width;
|
||||||
|
window->height = window->saved_height;
|
||||||
|
if (window->frame)
|
||||||
|
frame_resize_inside(window->frame,
|
||||||
|
window->width,
|
||||||
|
window->height);
|
||||||
|
weston_wm_window_configure(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
weston_wm_window_is_maximized(struct weston_wm_window *window)
|
||||||
|
{
|
||||||
|
return window->maximized_horz && window->maximized_vert;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
weston_wm_window_handle_state(struct weston_wm_window *window,
|
weston_wm_window_handle_state(struct weston_wm_window *window,
|
||||||
xcb_client_message_event_t *client_message)
|
xcb_client_message_event_t *client_message)
|
||||||
@@ -1339,6 +1375,7 @@ weston_wm_window_handle_state(struct weston_wm_window *window,
|
|||||||
struct weston_shell_interface *shell_interface =
|
struct weston_shell_interface *shell_interface =
|
||||||
&wm->server->compositor->shell_interface;
|
&wm->server->compositor->shell_interface;
|
||||||
uint32_t action, property;
|
uint32_t action, property;
|
||||||
|
int maximized = weston_wm_window_is_maximized(window);
|
||||||
|
|
||||||
action = client_message->data.data32[0];
|
action = client_message->data.data32[0];
|
||||||
property = client_message->data.data32[1];
|
property = client_message->data.data32[1];
|
||||||
@@ -1356,15 +1393,26 @@ weston_wm_window_handle_state(struct weston_wm_window *window,
|
|||||||
0, NULL);
|
0, NULL);
|
||||||
} else {
|
} else {
|
||||||
if (window->shsurf)
|
if (window->shsurf)
|
||||||
shell_interface->set_toplevel(window->shsurf);
|
weston_wm_window_set_toplevel(window);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (property == wm->atom.net_wm_state_maximized_vert &&
|
||||||
|
update_state(action, &window->maximized_vert))
|
||||||
|
weston_wm_window_set_net_wm_state(window);
|
||||||
|
if (property == wm->atom.net_wm_state_maximized_horz &&
|
||||||
|
update_state(action, &window->maximized_horz))
|
||||||
|
weston_wm_window_set_net_wm_state(window);
|
||||||
|
|
||||||
window->width = window->saved_width;
|
if (maximized != weston_wm_window_is_maximized(window)) {
|
||||||
window->height = window->saved_height;
|
if (weston_wm_window_is_maximized(window)) {
|
||||||
if (window->frame)
|
window->saved_width = window->width;
|
||||||
frame_resize_inside(window->frame,
|
window->saved_height = window->height;
|
||||||
window->width,
|
|
||||||
window->height);
|
if (window->shsurf)
|
||||||
weston_wm_window_configure(window);
|
shell_interface->set_maximized(window->shsurf);
|
||||||
|
} else if (window->shsurf) {
|
||||||
|
weston_wm_window_set_toplevel(window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1696,6 +1744,19 @@ weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event)
|
|||||||
weston_wm_window_close(window, button->time);
|
weston_wm_window_close(window, button->time);
|
||||||
frame_status_clear(window->frame, FRAME_STATUS_CLOSE);
|
frame_status_clear(window->frame, FRAME_STATUS_CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frame_status(window->frame) & FRAME_STATUS_MAXIMIZE) {
|
||||||
|
window->maximized_horz = !window->maximized_horz;
|
||||||
|
window->maximized_vert = !window->maximized_vert;
|
||||||
|
if (weston_wm_window_is_maximized(window)) {
|
||||||
|
window->saved_width = window->width;
|
||||||
|
window->saved_height = window->height;
|
||||||
|
shell_interface->set_maximized(window->shsurf);
|
||||||
|
} else {
|
||||||
|
weston_wm_window_set_toplevel(window);
|
||||||
|
}
|
||||||
|
frame_status_clear(window->frame, FRAME_STATUS_MAXIMIZE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1884,6 +1945,8 @@ weston_wm_get_resources(struct weston_wm *wm)
|
|||||||
{ "_NET_WM_PID", F(atom.net_wm_pid) },
|
{ "_NET_WM_PID", F(atom.net_wm_pid) },
|
||||||
{ "_NET_WM_ICON", F(atom.net_wm_icon) },
|
{ "_NET_WM_ICON", F(atom.net_wm_icon) },
|
||||||
{ "_NET_WM_STATE", F(atom.net_wm_state) },
|
{ "_NET_WM_STATE", F(atom.net_wm_state) },
|
||||||
|
{ "_NET_WM_STATE_MAXIMIZED_VERT", F(atom.net_wm_state_maximized_vert) },
|
||||||
|
{ "_NET_WM_STATE_MAXIMIZED_HORZ", F(atom.net_wm_state_maximized_horz) },
|
||||||
{ "_NET_WM_STATE_FULLSCREEN", F(atom.net_wm_state_fullscreen) },
|
{ "_NET_WM_STATE_FULLSCREEN", F(atom.net_wm_state_fullscreen) },
|
||||||
{ "_NET_WM_USER_TIME", F(atom.net_wm_user_time) },
|
{ "_NET_WM_USER_TIME", F(atom.net_wm_user_time) },
|
||||||
{ "_NET_WM_ICON_NAME", F(atom.net_wm_icon_name) },
|
{ "_NET_WM_ICON_NAME", F(atom.net_wm_icon_name) },
|
||||||
@@ -2061,7 +2124,7 @@ weston_wm_create(struct weston_xserver *wxs, int fd)
|
|||||||
struct wl_event_loop *loop;
|
struct wl_event_loop *loop;
|
||||||
xcb_screen_iterator_t s;
|
xcb_screen_iterator_t s;
|
||||||
uint32_t values[1];
|
uint32_t values[1];
|
||||||
xcb_atom_t supported[3];
|
xcb_atom_t supported[5];
|
||||||
|
|
||||||
wm = zalloc(sizeof *wm);
|
wm = zalloc(sizeof *wm);
|
||||||
if (wm == NULL)
|
if (wm == NULL)
|
||||||
@@ -2112,6 +2175,8 @@ weston_wm_create(struct weston_xserver *wxs, int fd)
|
|||||||
supported[0] = wm->atom.net_wm_moveresize;
|
supported[0] = wm->atom.net_wm_moveresize;
|
||||||
supported[1] = wm->atom.net_wm_state;
|
supported[1] = wm->atom.net_wm_state;
|
||||||
supported[2] = wm->atom.net_wm_state_fullscreen;
|
supported[2] = wm->atom.net_wm_state_fullscreen;
|
||||||
|
supported[3] = wm->atom.net_wm_state_maximized_vert;
|
||||||
|
supported[4] = wm->atom.net_wm_state_maximized_horz;
|
||||||
xcb_change_property(wm->conn,
|
xcb_change_property(wm->conn,
|
||||||
XCB_PROP_MODE_REPLACE,
|
XCB_PROP_MODE_REPLACE,
|
||||||
wm->screen->root,
|
wm->screen->root,
|
||||||
@@ -2389,6 +2454,8 @@ xserver_map_shell_surface(struct weston_wm_window *window,
|
|||||||
parent->surface,
|
parent->surface,
|
||||||
window->x - parent->x,
|
window->x - parent->x,
|
||||||
window->y - parent->y, flags);
|
window->y - parent->y, flags);
|
||||||
|
} else if (weston_wm_window_is_maximized(window)) {
|
||||||
|
shell_interface->set_maximized(window->shsurf);
|
||||||
} else {
|
} else {
|
||||||
if (weston_wm_window_type_inactive(window)) {
|
if (weston_wm_window_type_inactive(window)) {
|
||||||
shell_interface->set_xwayland(window->shsurf,
|
shell_interface->set_xwayland(window->shsurf,
|
||||||
|
|||||||
@@ -102,6 +102,8 @@ struct weston_wm {
|
|||||||
xcb_atom_t net_wm_pid;
|
xcb_atom_t net_wm_pid;
|
||||||
xcb_atom_t net_wm_icon;
|
xcb_atom_t net_wm_icon;
|
||||||
xcb_atom_t net_wm_state;
|
xcb_atom_t net_wm_state;
|
||||||
|
xcb_atom_t net_wm_state_maximized_vert;
|
||||||
|
xcb_atom_t net_wm_state_maximized_horz;
|
||||||
xcb_atom_t net_wm_state_fullscreen;
|
xcb_atom_t net_wm_state_fullscreen;
|
||||||
xcb_atom_t net_wm_user_time;
|
xcb_atom_t net_wm_user_time;
|
||||||
xcb_atom_t net_wm_icon_name;
|
xcb_atom_t net_wm_icon_name;
|
||||||
|
|||||||
Reference in New Issue
Block a user