better handling different window state, support fullscreen mode
This commit is contained in:
parent
1ae9cd000a
commit
bca498f387
14
cursor.c
14
cursor.c
@ -54,18 +54,16 @@ static void process_cursor_move(struct diyac_server *server, uint32_t time)
|
|||||||
{
|
{
|
||||||
struct diyac_view *toplevel = server->grabbed_view;
|
struct diyac_view *toplevel = server->grabbed_view;
|
||||||
/* Move the grabbed toplevel to the new position. */
|
/* Move the grabbed toplevel to the new position. */
|
||||||
if (toplevel->state == DIYAC_VIEW_FULL_SCREEN)
|
if (toplevel->state.fullscreen)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (toplevel->state == DIYAC_VIEW_MAXIMIZE)
|
if (toplevel->state.maximized)
|
||||||
{
|
{
|
||||||
// cancel maximize state
|
toplevel->requested.maximized = false;
|
||||||
wlr_xdg_toplevel_set_maximized(toplevel->xdg_toplevel, false);
|
|
||||||
// move the windows to cursor
|
// move the windows to cursor
|
||||||
server->grab_x = toplevel->original.width * server->grab_x / toplevel->output->usable_area.width;
|
server->grab_x = toplevel->original.width * server->grab_x / toplevel->output->usable_area.width;
|
||||||
}
|
}
|
||||||
toplevel->requested = DIYAC_VIEW_NORMAL;
|
|
||||||
toplevel->original.y = server->seat.cursor->y - server->grab_y;
|
toplevel->original.y = server->seat.cursor->y - server->grab_y;
|
||||||
toplevel->original.x = server->seat.cursor->x - server->grab_x;
|
toplevel->original.x = server->seat.cursor->x - server->grab_x;
|
||||||
|
|
||||||
@ -90,6 +88,10 @@ static void process_cursor_resize(struct diyac_server *server, uint32_t time)
|
|||||||
* size, then commit any movement that was prepared.
|
* size, then commit any movement that was prepared.
|
||||||
*/
|
*/
|
||||||
struct diyac_view *toplevel = server->grabbed_view;
|
struct diyac_view *toplevel = server->grabbed_view;
|
||||||
|
if(toplevel->state.fullscreen)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
double border_x = server->seat.cursor->x - server->grab_x;
|
double border_x = server->seat.cursor->x - server->grab_x;
|
||||||
double border_y = server->seat.cursor->y - server->grab_y;
|
double border_y = server->seat.cursor->y - server->grab_y;
|
||||||
int new_left = server->grab_geobox.x;
|
int new_left = server->grab_geobox.x;
|
||||||
@ -138,7 +140,7 @@ static void process_cursor_resize(struct diyac_server *server, uint32_t time)
|
|||||||
int new_height = new_bottom - new_top;
|
int new_height = new_bottom - new_top;
|
||||||
toplevel->original.width = new_width;
|
toplevel->original.width = new_width;
|
||||||
toplevel->original.height = new_height;
|
toplevel->original.height = new_height;
|
||||||
toplevel->requested = DIYAC_VIEW_NORMAL;
|
toplevel->requested.maximized = false;
|
||||||
diyac_view_update_geometry(toplevel, false);
|
diyac_view_update_geometry(toplevel, false);
|
||||||
/*
|
/*
|
||||||
wlr_scene_node_set_position(&toplevel->scene_tree->node,
|
wlr_scene_node_set_position(&toplevel->scene_tree->node,
|
||||||
|
16
diyac.h
16
diyac.h
@ -37,11 +37,15 @@ enum diyac_node_descriptor_type
|
|||||||
// LAB_NODE_TREE,
|
// LAB_NODE_TREE,
|
||||||
// LAB_NODE_SSD_BUTTON,
|
// LAB_NODE_SSD_BUTTON,
|
||||||
};
|
};
|
||||||
enum diyac_view_state
|
struct diyac_view_state
|
||||||
{
|
{
|
||||||
DIYAC_VIEW_NORMAL = 0,
|
bool maximized;
|
||||||
DIYAC_VIEW_MAXIMIZE,
|
bool fullscreen;
|
||||||
DIYAC_VIEW_FULL_SCREEN,
|
bool minimized;
|
||||||
|
/**
|
||||||
|
* if neither state is on, it means that
|
||||||
|
* the current state is normal
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct diyac_seat
|
struct diyac_seat
|
||||||
@ -165,8 +169,8 @@ struct diyac_view
|
|||||||
struct wlr_xdg_surface *xdg_surface;
|
struct wlr_xdg_surface *xdg_surface;
|
||||||
struct wlr_xdg_toplevel *xdg_toplevel;
|
struct wlr_xdg_toplevel *xdg_toplevel;
|
||||||
struct wlr_scene_tree *scene_tree;
|
struct wlr_scene_tree *scene_tree;
|
||||||
enum diyac_view_state state;
|
struct diyac_view_state state;
|
||||||
enum diyac_view_state requested;
|
struct diyac_view_state requested;
|
||||||
/*
|
/*
|
||||||
* Geometry of the wlr_surface contained within the view, as
|
* Geometry of the wlr_surface contained within the view, as
|
||||||
* currently displayed. Should be kept in sync with the
|
* currently displayed. Should be kept in sync with the
|
||||||
|
124
view.c
124
view.c
@ -172,72 +172,84 @@ bool diyac_view_update_geometry(struct diyac_view *view, bool grabbed)
|
|||||||
struct diyac_server *server = view->server;
|
struct diyac_server *server = view->server;
|
||||||
wlr_box_intersection(&intersect_box,geometry, &usable);
|
wlr_box_intersection(&intersect_box,geometry, &usable);
|
||||||
wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box);
|
wlr_xdg_surface_get_geometry(view->xdg_toplevel->base, &geo_box);
|
||||||
if ( wlr_box_equal(geometry, &geo_box) && (view->state == view->requested) && wlr_box_empty(&intersect_box))
|
if ( wlr_box_equal(geometry, &geo_box) && diyac_view_state_equal(view->state,view->requested) && wlr_box_empty(&intersect_box))
|
||||||
{
|
{
|
||||||
wlr_log(WLR_INFO, "No geometry update needed");
|
wlr_log(WLR_INFO, "No geometry update needed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// invalidate old state if change state
|
// invalidate old state if change state
|
||||||
if(view->requested != view->state)
|
if(view->state.fullscreen && !view->requested.fullscreen)
|
||||||
{
|
{
|
||||||
switch (view->state)
|
wlr_xdg_toplevel_set_fullscreen(view->xdg_toplevel, false);
|
||||||
{
|
wlr_scene_node_set_enabled(&view->output->scenes.top->node, true);
|
||||||
case DIYAC_VIEW_MAXIMIZE:
|
view->state.fullscreen = false;
|
||||||
wlr_xdg_toplevel_set_maximized(view->xdg_toplevel, false);
|
|
||||||
break;
|
|
||||||
case DIYAC_VIEW_FULL_SCREEN:
|
|
||||||
wlr_xdg_toplevel_set_fullscreen(view->xdg_toplevel, false);
|
|
||||||
wlr_scene_node_set_enabled(&view->output->scenes.top->node, true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
switch (view->requested)
|
if(view->state.maximized && !view->requested.maximized)
|
||||||
|
{
|
||||||
|
wlr_xdg_toplevel_set_maximized(view->xdg_toplevel, false);
|
||||||
|
view->state.maximized = false;
|
||||||
|
}
|
||||||
|
view->state = view->requested;
|
||||||
|
|
||||||
|
if(view->requested.minimized)
|
||||||
|
{
|
||||||
|
// TODO implement minimize
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(view->requested.fullscreen)
|
||||||
{
|
{
|
||||||
case DIYAC_VIEW_MAXIMIZE:
|
|
||||||
wlr_scene_node_set_position(&view->scene_tree->node, usable.x, usable.y);
|
|
||||||
wlr_xdg_toplevel_set_size(view->xdg_toplevel, usable.width, usable.height);
|
|
||||||
wlr_xdg_toplevel_set_maximized(view->xdg_toplevel, true);
|
|
||||||
view->state = DIYAC_VIEW_MAXIMIZE;
|
|
||||||
return true;
|
|
||||||
case DIYAC_VIEW_FULL_SCREEN:
|
|
||||||
wlr_scene_node_set_enabled(&view->output->scenes.top->node, false);
|
wlr_scene_node_set_enabled(&view->output->scenes.top->node, false);
|
||||||
wlr_scene_node_set_position(&view->scene_tree->node, 0, 0);
|
wlr_scene_node_set_position(&view->scene_tree->node, 0, 0);
|
||||||
wlr_xdg_toplevel_set_size(view->xdg_toplevel, view->output->wlr_output->width, view->output->wlr_output->height);
|
wlr_xdg_toplevel_set_size(view->xdg_toplevel, view->output->wlr_output->width, view->output->wlr_output->height);
|
||||||
view->state = DIYAC_VIEW_FULL_SCREEN;
|
|
||||||
wlr_xdg_toplevel_set_fullscreen(view->xdg_toplevel, false);
|
wlr_xdg_toplevel_set_fullscreen(view->xdg_toplevel, false);
|
||||||
return false;
|
return true;
|
||||||
|
}
|
||||||
default:
|
else if(view->requested.maximized)
|
||||||
|
{
|
||||||
|
wlr_scene_node_set_position(&view->scene_tree->node, usable.x, usable.y);
|
||||||
|
wlr_xdg_toplevel_set_size(view->xdg_toplevel, usable.width, usable.height);
|
||||||
|
wlr_xdg_toplevel_set_maximized(view->xdg_toplevel, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// if (wlr_output_layout_intersects(view->server->output_layout,
|
// if (wlr_output_layout_intersects(view->server->output_layout,
|
||||||
// view->output->wlr_output, &view->current))
|
// view->output->wlr_output, &view->current))
|
||||||
//{
|
//{
|
||||||
/**Normal state, recalculate current geometry*/
|
/**Normal state, recalculate current geometry*/
|
||||||
view->state = DIYAC_VIEW_NORMAL;
|
struct diyac_view * root = diyac_get_root_view(view);
|
||||||
if (!grabbed && geometry->x < usable.x)
|
if(!root)
|
||||||
{
|
{
|
||||||
geometry->x = usable.x;
|
root = view;
|
||||||
}
|
}
|
||||||
if (!grabbed && geometry->y < usable.y)
|
if(!root->state.fullscreen)
|
||||||
{
|
{
|
||||||
geometry->y = usable.y;
|
// Only adjust position only when not in fullscreen mode
|
||||||
}
|
|
||||||
if (grabbed && server->seat.cursor->x <= usable.x)
|
if (!grabbed && geometry->x < usable.x)
|
||||||
{
|
{
|
||||||
geometry->x = usable.x - server->grab_x;
|
geometry->x = usable.x;
|
||||||
}
|
}
|
||||||
if (grabbed && server->seat.cursor->y <= usable.y)
|
if (!grabbed && geometry->y < usable.y)
|
||||||
{
|
{
|
||||||
geometry->y = usable.y;
|
geometry->y = usable.y;
|
||||||
}
|
}
|
||||||
if (grabbed && server->seat.cursor->x >= usable.x + usable.width)
|
if (grabbed && server->seat.cursor->x <= usable.x)
|
||||||
{
|
{
|
||||||
geometry->x = usable.x + usable.width - server->grab_x;
|
geometry->x = usable.x - server->grab_x;
|
||||||
}
|
}
|
||||||
if (grabbed && server->seat.cursor->y >= usable.y + usable.height)
|
if (grabbed && server->seat.cursor->y <= usable.y)
|
||||||
{
|
{
|
||||||
geometry->y = usable.y + usable.height - server->grab_y;
|
geometry->y = usable.y;
|
||||||
|
}
|
||||||
|
if (grabbed && server->seat.cursor->x >= usable.x + usable.width)
|
||||||
|
{
|
||||||
|
geometry->x = usable.x + usable.width - server->grab_x;
|
||||||
|
}
|
||||||
|
if (grabbed && server->seat.cursor->y >= usable.y + usable.height)
|
||||||
|
{
|
||||||
|
geometry->y = usable.y + usable.height - server->grab_y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_log(WLR_DEBUG, "diyac_view_update_geometry: updating geometry: %d %d %d %d", geometry->x, geometry->y, geometry->width, geometry->height);
|
wlr_log(WLR_DEBUG, "diyac_view_update_geometry: updating geometry: %d %d %d %d", geometry->x, geometry->y, geometry->width, geometry->height);
|
||||||
@ -282,14 +294,14 @@ struct diyac_view *diyac_get_root_view(struct diyac_view *view)
|
|||||||
struct wlr_box diyac_view_get_geometry(struct diyac_view *view)
|
struct wlr_box diyac_view_get_geometry(struct diyac_view *view)
|
||||||
{
|
{
|
||||||
struct wlr_box box;
|
struct wlr_box box;
|
||||||
switch(view->state)
|
if(view->state.fullscreen)
|
||||||
{
|
{
|
||||||
case DIYAC_VIEW_FULL_SCREEN:
|
wlr_output_layout_get_box(view->server->output_layout, view->output->wlr_output, &box);
|
||||||
wlr_output_layout_get_box(view->server->output_layout, view->output->wlr_output, &box);
|
return box;
|
||||||
return box;
|
|
||||||
case DIYAC_VIEW_MAXIMIZE:
|
|
||||||
return view->output->usable_area;
|
|
||||||
default:
|
|
||||||
return view->original;
|
|
||||||
}
|
}
|
||||||
|
if(view->state.maximized)
|
||||||
|
{
|
||||||
|
return view->output->usable_area;
|
||||||
|
}
|
||||||
|
return view->original;
|
||||||
}
|
}
|
3
view.h
3
view.h
@ -1,6 +1,9 @@
|
|||||||
#ifndef DIYAC_VIEW_H
|
#ifndef DIYAC_VIEW_H
|
||||||
#define DIYAC_VIEW_H
|
#define DIYAC_VIEW_H
|
||||||
#include "diyac.h"
|
#include "diyac.h"
|
||||||
|
#define diyac_view_state_equal(a,b) ((a.fullscreen == b.fullscreen) \
|
||||||
|
&& (a.maximized == b.maximized) \
|
||||||
|
&& (a.minimized == b.minimized))
|
||||||
void diyac_focus_view(struct diyac_view *toplevel, bool raise);
|
void diyac_focus_view(struct diyac_view *toplevel, bool raise);
|
||||||
struct diyac_view *diyac_view_at(
|
struct diyac_view *diyac_view_at(
|
||||||
struct diyac_server *server, double lx, double ly,
|
struct diyac_server *server, double lx, double ly,
|
||||||
|
61
xdg.c
61
xdg.c
@ -92,6 +92,14 @@ static void xdg_toplevel_unmap(struct wl_listener *listener, void *data)
|
|||||||
{
|
{
|
||||||
diyac_reset_cursor_mode(toplevel->server);
|
diyac_reset_cursor_mode(toplevel->server);
|
||||||
}
|
}
|
||||||
|
if(toplevel->state.fullscreen)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* When a client exit during fullscreen mode, the top layer shall
|
||||||
|
* be restored as it is currently disabled
|
||||||
|
*/
|
||||||
|
wlr_scene_node_set_enabled(&toplevel->output->scenes.top->node, true);
|
||||||
|
}
|
||||||
wl_list_remove(&toplevel->link);
|
wl_list_remove(&toplevel->link);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +111,6 @@ static void xdg_toplevel_request_move(
|
|||||||
* decorations. Note that a more sophisticated compositor should check the
|
* decorations. Note that a more sophisticated compositor should check the
|
||||||
* provided serial against a list of button press serials sent to this
|
* provided serial against a list of button press serials sent to this
|
||||||
* client, to prevent the client from requesting this whenever they want. */
|
* client, to prevent the client from requesting this whenever they want. */
|
||||||
wlr_log(WLR_INFO, "Request move");
|
|
||||||
struct diyac_view *toplevel = wl_container_of(listener, toplevel, request_move);
|
struct diyac_view *toplevel = wl_container_of(listener, toplevel, request_move);
|
||||||
begin_interactive(toplevel, DIYAC_CURSOR_MOVE, 0);
|
begin_interactive(toplevel, DIYAC_CURSOR_MOVE, 0);
|
||||||
}
|
}
|
||||||
@ -116,7 +123,7 @@ static void xdg_toplevel_request_resize(
|
|||||||
* decorations. Note that a more sophisticated compositor should check the
|
* decorations. Note that a more sophisticated compositor should check the
|
||||||
* provided serial against a list of button press serials sent to this
|
* provided serial against a list of button press serials sent to this
|
||||||
* client, to prevent the client from requesting this whenever they want. */
|
* client, to prevent the client from requesting this whenever they want. */
|
||||||
wlr_log(WLR_INFO, "Request resize");
|
|
||||||
struct wlr_xdg_toplevel_resize_event *event = data;
|
struct wlr_xdg_toplevel_resize_event *event = data;
|
||||||
struct diyac_view *toplevel = wl_container_of(listener, toplevel, request_resize);
|
struct diyac_view *toplevel = wl_container_of(listener, toplevel, request_resize);
|
||||||
begin_interactive(toplevel, DIYAC_CURSOR_RESIZE, event->edges);
|
begin_interactive(toplevel, DIYAC_CURSOR_RESIZE, event->edges);
|
||||||
@ -133,15 +140,7 @@ static void xdg_toplevel_request_maximize(
|
|||||||
|
|
||||||
struct diyac_view *toplevel =
|
struct diyac_view *toplevel =
|
||||||
wl_container_of(listener, toplevel, request_maximize);
|
wl_container_of(listener, toplevel, request_maximize);
|
||||||
if(toplevel->xdg_toplevel->requested.maximized)
|
toplevel->requested.maximized = toplevel->xdg_toplevel->requested.maximized;
|
||||||
{
|
|
||||||
toplevel->requested = DIYAC_VIEW_MAXIMIZE;
|
|
||||||
}
|
|
||||||
else if(toplevel->state == DIYAC_VIEW_MAXIMIZE)
|
|
||||||
{
|
|
||||||
toplevel->requested = DIYAC_VIEW_NORMAL;
|
|
||||||
}
|
|
||||||
wlr_log(WLR_INFO, "Request maximize");
|
|
||||||
diyac_reset_cursor_mode(toplevel->server);
|
diyac_reset_cursor_mode(toplevel->server);
|
||||||
diyac_view_update_geometry(toplevel, false);
|
diyac_view_update_geometry(toplevel, false);
|
||||||
}
|
}
|
||||||
@ -150,15 +149,11 @@ static void xdg_toplevel_request_fullscreen(struct wl_listener *listener, void *
|
|||||||
{
|
{
|
||||||
struct diyac_view *toplevel =
|
struct diyac_view *toplevel =
|
||||||
wl_container_of(listener, toplevel, request_fullscreen);
|
wl_container_of(listener, toplevel, request_fullscreen);
|
||||||
if(toplevel->xdg_toplevel->requested.fullscreen)
|
toplevel->requested.fullscreen = toplevel->xdg_toplevel->requested.fullscreen;
|
||||||
{
|
/**
|
||||||
toplevel->requested = DIYAC_VIEW_FULL_SCREEN;
|
* TODO: use client specific output for fullscreen
|
||||||
}
|
* toplevel->xdg_toplevel->requested.fullscreen_output
|
||||||
else if(toplevel->state == DIYAC_VIEW_FULL_SCREEN)
|
*/
|
||||||
{
|
|
||||||
toplevel->requested = DIYAC_VIEW_NORMAL;
|
|
||||||
}
|
|
||||||
wlr_log(WLR_INFO, "Request fullscreen");
|
|
||||||
diyac_reset_cursor_mode(toplevel->server);
|
diyac_reset_cursor_mode(toplevel->server);
|
||||||
diyac_view_update_geometry(toplevel, false);
|
diyac_view_update_geometry(toplevel, false);
|
||||||
}
|
}
|
||||||
@ -167,6 +162,8 @@ static void xdg_toplevel_request_minimize(struct wl_listener *listener, void *da
|
|||||||
{
|
{
|
||||||
struct diyac_view *toplevel =
|
struct diyac_view *toplevel =
|
||||||
wl_container_of(listener, toplevel, request_minimize);
|
wl_container_of(listener, toplevel, request_minimize);
|
||||||
|
toplevel->requested.minimized = toplevel->xdg_toplevel->requested.minimized;
|
||||||
|
//TODO implement minimize
|
||||||
wlr_xdg_surface_schedule_configure(toplevel->xdg_toplevel->base);
|
wlr_xdg_surface_schedule_configure(toplevel->xdg_toplevel->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,13 +212,23 @@ static void popup_unconstrain(struct diyac_popup *popup)
|
|||||||
struct diyac_server *server = view->server;
|
struct diyac_server *server = view->server;
|
||||||
struct wlr_output_layout *output_layout = server->output_layout;
|
struct wlr_output_layout *output_layout = server->output_layout;
|
||||||
struct wlr_output *wlr_output = view->output->wlr_output;
|
struct wlr_output *wlr_output = view->output->wlr_output;
|
||||||
|
struct wlr_box usable = {
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = view->output->wlr_output->width,
|
||||||
|
.height = view->output->wlr_output->height
|
||||||
|
};
|
||||||
|
struct diyac_view *root = diyac_get_root_view(view);
|
||||||
|
if(!root || ! root->state.fullscreen)
|
||||||
|
{
|
||||||
|
usable = view->output->usable_area;
|
||||||
|
}
|
||||||
struct wlr_box geo_box = diyac_view_get_geometry(view);
|
struct wlr_box geo_box = diyac_view_get_geometry(view);
|
||||||
struct wlr_box output_toplevel_box = {
|
struct wlr_box output_toplevel_box = {
|
||||||
.x = view->output->usable_area.x - geo_box.x,
|
.x = usable.x - geo_box.x,
|
||||||
.y = view->output->usable_area.y - geo_box.y,
|
.y = usable.y - geo_box.y,
|
||||||
.width = view->output->usable_area.width,
|
.width = usable.width,
|
||||||
.height = view->output->usable_area.height,
|
.height = usable.height,
|
||||||
};
|
};
|
||||||
wlr_xdg_popup_unconstrain_from_box(popup->wlr_popup, &output_toplevel_box);
|
wlr_xdg_popup_unconstrain_from_box(popup->wlr_popup, &output_toplevel_box);
|
||||||
}
|
}
|
||||||
@ -350,8 +357,8 @@ void diyac_new_xdg_surface(struct wl_listener *listener, void *data)
|
|||||||
wlr_xdg_surface_ping(xdg_surface);
|
wlr_xdg_surface_ping(xdg_surface);
|
||||||
/* Allocate a diyac_view for this surface */
|
/* Allocate a diyac_view for this surface */
|
||||||
struct diyac_view *toplevel = calloc(1, sizeof(*toplevel));
|
struct diyac_view *toplevel = calloc(1, sizeof(*toplevel));
|
||||||
toplevel->state = DIYAC_VIEW_NORMAL;
|
memset(&toplevel->state, 0, sizeof(toplevel->state));
|
||||||
toplevel->requested = DIYAC_VIEW_NORMAL;
|
memset(&toplevel->requested, 0, sizeof(toplevel->requested));
|
||||||
toplevel->server = server;
|
toplevel->server = server;
|
||||||
toplevel->xdg_toplevel = xdg_surface->toplevel;
|
toplevel->xdg_toplevel = xdg_surface->toplevel;
|
||||||
toplevel->xdg_surface = xdg_surface;
|
toplevel->xdg_surface = xdg_surface;
|
||||||
|
Loading…
Reference in New Issue
Block a user