[digesting_libdecor] collapse some couple code paths into 'update_client_side_rendering_state'
parent
abac463a70
commit
fb2af4f143
|
|
@ -1129,34 +1129,6 @@ int main(){
|
||||||
|
|
||||||
//#include "libdecor.c"
|
//#include "libdecor.c"
|
||||||
|
|
||||||
static void
|
|
||||||
frame_get_window_size_for(struct libdecor_state *state, int *window_width, int *window_height){
|
|
||||||
*window_width = state->content_width;
|
|
||||||
*window_height = state->content_height;
|
|
||||||
if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
|
|
||||||
Sides2D border_size = border_size_from_window_state(ctx.frame_window_state);
|
|
||||||
*window_width += border_size.x[0] + border_size.x[1];
|
|
||||||
*window_height += border_size.y[0] + border_size.y[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
frame_set_window_geometry(int32_t w, int32_t h){
|
|
||||||
Extent2D extent = {0};
|
|
||||||
extent.w = w;
|
|
||||||
extent.w = h;
|
|
||||||
|
|
||||||
if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
|
|
||||||
Sides2D border_size = border_size_from_window_state(ctx.frame_window_state);
|
|
||||||
extent.x = -border_size.x[0];
|
|
||||||
extent.y = -border_size.y[0];
|
|
||||||
extent.w = w + border_size.x[0] + border_size.x[1];
|
|
||||||
extent.h = h + border_size.y[0] + border_size.y[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
xdg_surface_set_window_geometry(ctx.xdg_surface, extent.x, extent.y, extent.w, extent.h);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
libdecor_configuration_get_content_size(struct libdecor_configuration *configuration, int *width, int *height){
|
libdecor_configuration_get_content_size(struct libdecor_configuration *configuration, int *width, int *height){
|
||||||
/* get configured toplevel dimensions */
|
/* get configured toplevel dimensions */
|
||||||
|
|
@ -1202,17 +1174,119 @@ libdecor_configuration_get_content_size(struct libdecor_configuration *configura
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum decoration_type
|
||||||
|
decoration_type_from_window_state(enum libdecor_window_state window_state){
|
||||||
|
enum decoration_type result = DECORATION_TYPE_ALL;
|
||||||
|
if (window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN){
|
||||||
|
result = DECORATION_TYPE_NONE;
|
||||||
|
}
|
||||||
|
else if (window_state & (LIBDECOR_WINDOW_STATE_MAXIMIZED |
|
||||||
|
LIBDECOR_WINDOW_STATE_TILED_LEFT |
|
||||||
|
LIBDECOR_WINDOW_STATE_TILED_RIGHT |
|
||||||
|
LIBDECOR_WINDOW_STATE_TILED_TOP |
|
||||||
|
LIBDECOR_WINDOW_STATE_TILED_BOTTOM)){
|
||||||
|
result = DECORATION_TYPE_TITLE_ONLY;
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_border_component(struct border_component *border_component){
|
||||||
|
if (border_component->wl_surface) {
|
||||||
|
wl_subsurface_destroy(border_component->wl_subsurface);
|
||||||
|
border_component->wl_subsurface = NULL;
|
||||||
|
wl_surface_destroy(border_component->wl_surface);
|
||||||
|
border_component->wl_surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (border_component->wl_buffer != 0){
|
||||||
|
wl_buffer_destroy(border_component->wl_buffer);
|
||||||
|
}
|
||||||
|
if (border_component->data != 0){
|
||||||
|
munmap(border_component->data, border_component->data_size);
|
||||||
|
}
|
||||||
|
border_component->wl_buffer = 0;
|
||||||
|
border_component->data = 0;
|
||||||
|
border_component->data_size = 0;
|
||||||
|
border_component->width = 0;
|
||||||
|
border_component->height = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
update_client_side_rendering_state(void){
|
||||||
|
if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
|
||||||
|
enum libdecor_window_state old_window_state;
|
||||||
|
enum libdecor_window_state new_window_state;
|
||||||
|
int old_content_width, old_content_height;
|
||||||
|
int new_content_width, new_content_height;
|
||||||
|
enum decoration_type old_decoration_type;
|
||||||
|
enum decoration_type new_decoration_type;
|
||||||
|
|
||||||
|
old_window_state = ctx.gtk_window_state;
|
||||||
|
new_window_state = ctx.frame_window_state;
|
||||||
|
|
||||||
|
old_content_width = ctx.gtk_content_width;
|
||||||
|
old_content_height = ctx.gtk_content_height;
|
||||||
|
new_content_width = ctx.frame_content_width;
|
||||||
|
new_content_height = ctx.frame_content_height;
|
||||||
|
|
||||||
|
old_decoration_type = ctx.decoration_type;
|
||||||
|
new_decoration_type = decoration_type_from_window_state(new_window_state);
|
||||||
|
|
||||||
|
if (old_decoration_type != new_decoration_type ||
|
||||||
|
old_content_width != new_content_width ||
|
||||||
|
old_content_height != new_content_height ||
|
||||||
|
old_window_state != new_window_state){
|
||||||
|
|
||||||
|
ctx.gtk_content_width = new_content_width;
|
||||||
|
ctx.gtk_content_height = new_content_height;
|
||||||
|
ctx.gtk_window_state = new_window_state;
|
||||||
|
ctx.decoration_type = new_decoration_type;
|
||||||
|
|
||||||
|
draw_decoration();
|
||||||
|
|
||||||
|
/* set fixed window size */
|
||||||
|
if (!(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
|
||||||
|
ctx.size_bounds.x[0] = ctx.gtk_content_width;
|
||||||
|
ctx.size_bounds.y[0] = ctx.gtk_content_height;
|
||||||
|
ctx.size_bounds.x[1] = ctx.gtk_content_width;
|
||||||
|
ctx.size_bounds.y[1] = ctx.gtk_content_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
g_clear_pointer(&ctx.header, gtk_widget_destroy);
|
||||||
|
g_clear_pointer(&ctx.window, gtk_widget_destroy);
|
||||||
|
|
||||||
|
free_border_component(&ctx.component_slot[COMPONENT_SLOT_HEADER]);
|
||||||
|
free_border_component(&ctx.component_slot[COMPONENT_SLOT_SHADOW]);
|
||||||
|
ctx.shadow_showing = false;
|
||||||
|
|
||||||
|
g_clear_pointer(&ctx.title, free);
|
||||||
|
|
||||||
|
ctx.decoration_type = DECORATION_TYPE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Extent2D extent = {0};
|
||||||
|
extent.w = ctx.frame_content_width;
|
||||||
|
extent.h = ctx.frame_content_height;
|
||||||
|
|
||||||
|
if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
|
||||||
|
Sides2D border_size = border_size_from_window_state(ctx.frame_window_state);
|
||||||
|
extent.x = -border_size.x[0];
|
||||||
|
extent.y = -border_size.y[0];
|
||||||
|
extent.w += border_size.x[0] + border_size.x[1];
|
||||||
|
extent.h += border_size.y[0] + border_size.y[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
xdg_surface_set_window_geometry(ctx.xdg_surface, extent.x, extent.y, extent.w, extent.h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
libdecor_frame_set_visibility(bool visible){
|
libdecor_frame_set_visibility(bool visible){
|
||||||
ctx.visible = visible;
|
ctx.visible = visible;
|
||||||
|
|
||||||
/* enable/disable decorations that are managed by the compositor.
|
|
||||||
* Note that, as of xdg_decoration v1, this is just a hint and there is
|
|
||||||
* no reliable way of disabling all decorations. In practice this should
|
|
||||||
* work but per spec this is not guaranteed.
|
|
||||||
*
|
|
||||||
* See also: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/17
|
|
||||||
*/
|
|
||||||
if (ctx.decoration_manager != 0 &&
|
if (ctx.decoration_manager != 0 &&
|
||||||
ctx.toplevel_decoration != 0 &&
|
ctx.toplevel_decoration != 0 &&
|
||||||
ctx.has_decoration_mode &&
|
ctx.has_decoration_mode &&
|
||||||
|
|
@ -1225,15 +1299,7 @@ libdecor_frame_set_visibility(bool visible){
|
||||||
|
|
||||||
if (ctx.frame_content_width > 0 &&
|
if (ctx.frame_content_width > 0 &&
|
||||||
ctx.frame_content_height > 0){
|
ctx.frame_content_height > 0){
|
||||||
if (ctx.visible != 0 &&
|
update_client_side_rendering_state();
|
||||||
ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
|
|
||||||
libdecor_plugin_gtk_frame_commit();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
libdecor_plugin_gtk_frame_free();
|
|
||||||
}
|
|
||||||
|
|
||||||
frame_set_window_geometry(ctx.frame_content_width, ctx.frame_content_height);
|
|
||||||
|
|
||||||
wl_surface_commit(ctx.wl_surface);
|
wl_surface_commit(ctx.wl_surface);
|
||||||
}
|
}
|
||||||
|
|
@ -1268,24 +1334,22 @@ libdecor_frame_unset_fullscreen(void){
|
||||||
|
|
||||||
void
|
void
|
||||||
libdecor_frame_commit(int w, int h, struct libdecor_configuration *configuration){
|
libdecor_frame_commit(int w, int h, struct libdecor_configuration *configuration){
|
||||||
|
if (configuration != 0 && configuration->has_window_state){
|
||||||
|
ctx.frame_window_state = configuration->window_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sides2D border_size = border_size_from_window_state(ctx.frame_window_state);
|
||||||
|
int border_added_w = border_size.x[0] + border_size.x[1];
|
||||||
|
int border_added_h = border_size.y[0] + border_size.y[1];
|
||||||
|
|
||||||
struct libdecor_state state = {0};
|
struct libdecor_state state = {0};
|
||||||
state.content_width = w;
|
state.content_width = w;
|
||||||
state.content_height = h;
|
state.content_height = h;
|
||||||
|
state.window_state = ctx.frame_window_state;
|
||||||
if (configuration != 0 && configuration->has_window_state){
|
|
||||||
ctx.frame_window_state = configuration->window_state;
|
|
||||||
state.window_state = configuration->window_state;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
state.window_state = ctx.frame_window_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.frame_content_width = state.content_width;
|
ctx.frame_content_width = state.content_width;
|
||||||
ctx.frame_content_height = state.content_height;
|
ctx.frame_content_height = state.content_height;
|
||||||
{
|
{
|
||||||
/* If the frame is configured as non-resizable before the first
|
|
||||||
* configure event is received, we have to manually set the min/max
|
|
||||||
* limits with the configured content size afterwards. */
|
|
||||||
if (!(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
|
if (!(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
|
||||||
ctx.size_bounds.x[0] = ctx.frame_content_width;
|
ctx.size_bounds.x[0] = ctx.frame_content_width;
|
||||||
ctx.size_bounds.y[0] = ctx.frame_content_height;
|
ctx.size_bounds.y[0] = ctx.frame_content_height;
|
||||||
|
|
@ -1293,49 +1357,27 @@ libdecor_frame_commit(int w, int h, struct libdecor_configuration *configuration
|
||||||
ctx.size_bounds.y[1] = ctx.frame_content_height;
|
ctx.size_bounds.y[1] = ctx.frame_content_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.size_bounds.x[0] > 0 &&
|
for (int i = 0; i < 2; i += 1){
|
||||||
ctx.size_bounds.y[0] > 0){
|
int w = 0;
|
||||||
struct libdecor_state state_min;
|
int h = 0;
|
||||||
int win_min_width, win_min_height;
|
if (ctx.size_bounds.x[i] > 0 && ctx.size_bounds.y[i] > 0){
|
||||||
|
w = ctx.size_bounds.x[i];
|
||||||
state_min.content_width = ctx.size_bounds.x[0];
|
h = ctx.size_bounds.y[i];
|
||||||
state_min.content_height = ctx.size_bounds.y[0];
|
if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
|
||||||
state_min.window_state = state.window_state;
|
w += border_added_w;
|
||||||
|
h += border_added_h;
|
||||||
frame_get_window_size_for(&state_min, &win_min_width, &win_min_height);
|
}
|
||||||
xdg_toplevel_set_min_size(ctx.xdg_toplevel, win_min_width, win_min_height);
|
}
|
||||||
}
|
if (i == 0){
|
||||||
else{
|
xdg_toplevel_set_min_size(ctx.xdg_toplevel, w, h);
|
||||||
xdg_toplevel_set_min_size(ctx.xdg_toplevel, 0, 0);
|
}
|
||||||
}
|
else{
|
||||||
|
xdg_toplevel_set_max_size(ctx.xdg_toplevel, w, h);
|
||||||
if (ctx.size_bounds.x[1] > 0 &&
|
}
|
||||||
ctx.size_bounds.y[1] > 0){
|
|
||||||
struct libdecor_state state_max;
|
|
||||||
int win_max_width, win_max_height;
|
|
||||||
|
|
||||||
state_max.content_width = ctx.size_bounds.x[1];
|
|
||||||
state_max.content_height = ctx.size_bounds.y[1];
|
|
||||||
state_max.window_state = state.window_state;
|
|
||||||
|
|
||||||
frame_get_window_size_for(&state_max, &win_max_width, &win_max_height);
|
|
||||||
xdg_toplevel_set_max_size(ctx.xdg_toplevel, win_max_width, win_max_height);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
xdg_toplevel_set_max_size(ctx.xdg_toplevel, 0, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* switch between decoration modes */
|
update_client_side_rendering_state();
|
||||||
if (ctx.visible &&
|
|
||||||
ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
|
|
||||||
libdecor_plugin_gtk_frame_commit();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
libdecor_plugin_gtk_frame_free();
|
|
||||||
}
|
|
||||||
|
|
||||||
frame_set_window_geometry(ctx.frame_content_width, ctx.frame_content_height);
|
|
||||||
|
|
||||||
if (configuration != 0){
|
if (configuration != 0){
|
||||||
xdg_surface_ack_configure(ctx.xdg_surface, configuration->serial);
|
xdg_surface_ack_configure(ctx.xdg_surface, configuration->serial);
|
||||||
|
|
@ -1829,43 +1871,6 @@ toggle_maximized(void){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
free_border_component(struct border_component *border_component){
|
|
||||||
if (border_component->wl_surface) {
|
|
||||||
wl_subsurface_destroy(border_component->wl_subsurface);
|
|
||||||
border_component->wl_subsurface = NULL;
|
|
||||||
wl_surface_destroy(border_component->wl_surface);
|
|
||||||
border_component->wl_surface = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (border_component->wl_buffer != 0){
|
|
||||||
wl_buffer_destroy(border_component->wl_buffer);
|
|
||||||
}
|
|
||||||
if (border_component->data != 0){
|
|
||||||
munmap(border_component->data, border_component->data_size);
|
|
||||||
}
|
|
||||||
border_component->wl_buffer = 0;
|
|
||||||
border_component->data = 0;
|
|
||||||
border_component->data_size = 0;
|
|
||||||
border_component->width = 0;
|
|
||||||
border_component->height = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
libdecor_plugin_gtk_frame_free(void){
|
|
||||||
g_clear_pointer(&ctx.header, gtk_widget_destroy);
|
|
||||||
g_clear_pointer(&ctx.window, gtk_widget_destroy);
|
|
||||||
|
|
||||||
free_border_component(&ctx.component_slot[COMPONENT_SLOT_HEADER]);
|
|
||||||
free_border_component(&ctx.component_slot[COMPONENT_SLOT_SHADOW]);
|
|
||||||
ctx.shadow_showing = false;
|
|
||||||
|
|
||||||
g_clear_pointer(&ctx.shadow_blur, cairo_surface_destroy);
|
|
||||||
g_clear_pointer(&ctx.title, free);
|
|
||||||
|
|
||||||
ctx.decoration_type = DECORATION_TYPE_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hide_border_component(struct border_component *border_component){
|
hide_border_component(struct border_component *border_component){
|
||||||
if (border_component->wl_surface){
|
if (border_component->wl_surface){
|
||||||
|
|
@ -2345,64 +2350,6 @@ draw_decoration(void){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum decoration_type
|
|
||||||
decoration_type_from_window_state(enum libdecor_window_state window_state){
|
|
||||||
enum decoration_type result = DECORATION_TYPE_ALL;
|
|
||||||
if (window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN){
|
|
||||||
result = DECORATION_TYPE_NONE;
|
|
||||||
}
|
|
||||||
else if (window_state & (LIBDECOR_WINDOW_STATE_MAXIMIZED |
|
|
||||||
LIBDECOR_WINDOW_STATE_TILED_LEFT |
|
|
||||||
LIBDECOR_WINDOW_STATE_TILED_RIGHT |
|
|
||||||
LIBDECOR_WINDOW_STATE_TILED_TOP |
|
|
||||||
LIBDECOR_WINDOW_STATE_TILED_BOTTOM)){
|
|
||||||
result = DECORATION_TYPE_TITLE_ONLY;
|
|
||||||
}
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
libdecor_plugin_gtk_frame_commit(void){
|
|
||||||
enum libdecor_window_state old_window_state;
|
|
||||||
enum libdecor_window_state new_window_state;
|
|
||||||
int old_content_width, old_content_height;
|
|
||||||
int new_content_width, new_content_height;
|
|
||||||
enum decoration_type old_decoration_type;
|
|
||||||
enum decoration_type new_decoration_type;
|
|
||||||
|
|
||||||
old_window_state = ctx.gtk_window_state;
|
|
||||||
new_window_state = ctx.frame_window_state;
|
|
||||||
|
|
||||||
old_content_width = ctx.gtk_content_width;
|
|
||||||
old_content_height = ctx.gtk_content_height;
|
|
||||||
new_content_width = ctx.frame_content_width;
|
|
||||||
new_content_height = ctx.frame_content_height;
|
|
||||||
|
|
||||||
old_decoration_type = ctx.decoration_type;
|
|
||||||
new_decoration_type = decoration_type_from_window_state(new_window_state);
|
|
||||||
|
|
||||||
if (old_decoration_type != new_decoration_type ||
|
|
||||||
old_content_width != new_content_width ||
|
|
||||||
old_content_height != new_content_height ||
|
|
||||||
old_window_state != new_window_state){
|
|
||||||
|
|
||||||
ctx.gtk_content_width = new_content_width;
|
|
||||||
ctx.gtk_content_height = new_content_height;
|
|
||||||
ctx.gtk_window_state = new_window_state;
|
|
||||||
ctx.decoration_type = new_decoration_type;
|
|
||||||
|
|
||||||
draw_decoration();
|
|
||||||
|
|
||||||
/* set fixed window size */
|
|
||||||
if (!(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
|
|
||||||
ctx.size_bounds.x[0] = ctx.gtk_content_width;
|
|
||||||
ctx.size_bounds.y[0] = ctx.gtk_content_height;
|
|
||||||
ctx.size_bounds.x[1] = ctx.gtk_content_width;
|
|
||||||
ctx.size_bounds.y[1] = ctx.gtk_content_height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Sides2D
|
static Sides2D
|
||||||
border_size_from_window_state(enum libdecor_window_state window_state){
|
border_size_from_window_state(enum libdecor_window_state window_state){
|
||||||
Sides2D border_size = {0};
|
Sides2D border_size = {0};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue