diff --git a/include/ssd-internal.h b/include/ssd-internal.h index bfc11018..82652f2c 100644 --- a/include/ssd-internal.h +++ b/include/ssd-internal.h @@ -23,6 +23,8 @@ struct ssd_button { struct wlr_scene_node *toggled; struct wlr_scene_node *toggled_hover; struct wlr_scene_node *background; + struct wlr_scene_tree *icon_tree; + struct wlr_scene_tree *hover_tree; struct wl_listener destroy; }; @@ -47,7 +49,7 @@ struct ssd { * don't update things we don't have to. */ struct { - bool squared_corners; /* To un-round corner buttons on maximize */ + bool was_maximized; /* To un-round corner buttons and toggle icon on maximize */ struct wlr_box geometry; struct ssd_state_title { char *text; @@ -99,9 +101,7 @@ struct ssd_part { struct ssd_hover_state { struct view *view; - struct wlr_scene_node *node; - struct wlr_scene_node *old_node; - int maximized; + struct ssd_button *button; }; struct wlr_buffer; diff --git a/src/ssd/ssd.c b/src/ssd/ssd.c index 0f1eafca..df18f1e5 100644 --- a/src/ssd/ssd.c +++ b/src/ssd/ssd.c @@ -227,9 +227,15 @@ ssd_update_geometry(struct ssd *ssd) ssd->state.geometry = current; } bool maximized = (ssd->view->maximized == VIEW_AXIS_BOTH); - if (ssd->state.squared_corners != maximized) { + if (ssd->state.was_maximized != maximized) { ssd_border_update(ssd); ssd_titlebar_update(ssd); + /* + * Not strictly necessary as ssd_titlebar_update() + * already sets state.was_maximized but to future + * proof this a bit we also set it here again. + */ + ssd->state.was_maximized = maximized; } return; } @@ -265,7 +271,7 @@ ssd_destroy(struct ssd *ssd) hover_state = view->server->ssd_hover_state; if (hover_state->view == view) { hover_state->view = NULL; - hover_state->node = NULL; + hover_state->button = NULL; } /* Destroy subcomponents */ diff --git a/src/ssd/ssd_part.c b/src/ssd/ssd_part.c index ea53c104..20a9ad3a 100644 --- a/src/ssd/ssd_part.c +++ b/src/ssd/ssd_part.c @@ -154,10 +154,11 @@ add_scene_button(struct wl_list *part_list, enum ssd_part_type type, SSD_BUTTON_WIDTH, rc.theme->title_height, 0, 0, bg_color); /* Icon */ + struct wlr_scene_tree *icon_tree = wlr_scene_tree_create(parent); struct wlr_box icon_geo = get_scale_box(icon_buffer, SSD_BUTTON_WIDTH, rc.theme->title_height); struct ssd_part *icon_part = add_scene_buffer(part_list, type, - parent, icon_buffer, icon_geo.x, icon_geo.y); + icon_tree, icon_buffer, icon_geo.x, icon_geo.y); /* Make sure big icons are scaled down if necessary */ wlr_scene_buffer_set_dest_size( @@ -165,18 +166,18 @@ add_scene_button(struct wl_list *part_list, enum ssd_part_type type, icon_geo.width, icon_geo.height); /* Hover icon */ + struct wlr_scene_tree *hover_tree = wlr_scene_tree_create(parent); + wlr_scene_node_set_enabled(&hover_tree->node, false); struct wlr_box hover_geo = get_scale_box(hover_buffer, SSD_BUTTON_WIDTH, rc.theme->title_height); struct ssd_part *hover_part = add_scene_buffer(part_list, type, - parent, hover_buffer, hover_geo.x, hover_geo.y); + hover_tree, hover_buffer, hover_geo.x, hover_geo.y); /* Make sure big icons are scaled down if necessary */ wlr_scene_buffer_set_dest_size( wlr_scene_buffer_from_node(hover_part->node), hover_geo.width, hover_geo.height); - wlr_scene_node_set_enabled(hover_part->node, false); - struct ssd_button *button = ssd_button_descriptor_create(button_root->node); button->type = type; button->view = view; @@ -185,6 +186,8 @@ add_scene_button(struct wl_list *part_list, enum ssd_part_type type, button->background = bg_rect->node; button->toggled = NULL; button->toggled_hover = NULL; + button->icon_tree = icon_tree; + button->hover_tree = hover_tree; return button_root; } @@ -194,14 +197,13 @@ add_toggled_icon(struct wl_list *part_list, enum ssd_part_type type, { struct ssd_part *part = ssd_get_part(part_list, type); struct ssd_button *button = node_ssd_button_from_node(part->node); - struct wlr_scene_tree *parent = wlr_scene_tree_from_node(part->node); /* Alternate icon */ struct wlr_box icon_geo = get_scale_box(icon_buffer, SSD_BUTTON_WIDTH, rc.theme->title_height); struct ssd_part *alticon_part = add_scene_buffer(part_list, type, - parent, icon_buffer, icon_geo.x, icon_geo.y); + button->icon_tree, icon_buffer, icon_geo.x, icon_geo.y); wlr_scene_buffer_set_dest_size( wlr_scene_buffer_from_node(alticon_part->node), @@ -212,7 +214,7 @@ add_toggled_icon(struct wl_list *part_list, enum ssd_part_type type, struct wlr_box hover_geo = get_scale_box(hover_buffer, SSD_BUTTON_WIDTH, rc.theme->title_height); struct ssd_part *althover_part = add_scene_buffer(part_list, type, - parent, hover_buffer, hover_geo.x, hover_geo.y); + button->hover_tree, hover_buffer, hover_geo.x, hover_geo.y); wlr_scene_buffer_set_dest_size( wlr_scene_buffer_from_node(althover_part->node), diff --git a/src/ssd/ssd_titlebar.c b/src/ssd/ssd_titlebar.c index fc28e64a..f3167162 100644 --- a/src/ssd/ssd_titlebar.c +++ b/src/ssd/ssd_titlebar.c @@ -18,6 +18,7 @@ &(ssd)->titlebar.inactive) static void set_squared_corners(struct ssd *ssd, bool enable); +static void set_maximize_alt_icon(struct ssd *ssd, bool enable); void ssd_titlebar_create(struct ssd *ssd) @@ -109,6 +110,8 @@ ssd_titlebar_create(struct ssd *ssd) if (view->maximized == VIEW_AXIS_BOTH) { set_squared_corners(ssd, true); + set_maximize_alt_icon(ssd, true); + ssd->state.was_maximized = true; } } @@ -143,8 +146,29 @@ set_squared_corners(struct ssd *ssd, bool enable) wlr_scene_node_set_enabled(rounded_corner, !enable); } } FOR_EACH_END +} - ssd->state.squared_corners = enable; +static void +set_maximize_alt_icon(struct ssd *ssd, bool enable) +{ + struct ssd_part *part; + struct ssd_button *button; + struct ssd_sub_tree *subtree; + + FOR_EACH_STATE(ssd, subtree) { + part = ssd_get_part(&subtree->parts, LAB_SSD_BUTTON_MAXIMIZE); + button = node_ssd_button_from_node(part->node); + + if (button->toggled) { + wlr_scene_node_set_enabled(button->toggled, enable); + wlr_scene_node_set_enabled(button->normal, !enable); + } + + if (button->toggled_hover) { + wlr_scene_node_set_enabled(button->toggled_hover, enable); + wlr_scene_node_set_enabled(button->hover, !enable); + } + } FOR_EACH_END } void @@ -155,8 +179,10 @@ ssd_titlebar_update(struct ssd *ssd) struct theme *theme = view->server->theme; bool maximized = (view->maximized == VIEW_AXIS_BOTH); - if (ssd->state.squared_corners != maximized) { + if (ssd->state.was_maximized != maximized) { set_squared_corners(ssd, maximized); + set_maximize_alt_icon(ssd, maximized); + ssd->state.was_maximized = maximized; } if (width == ssd->state.geometry.width) { @@ -184,18 +210,6 @@ ssd_titlebar_update(struct ssd *ssd) if (is_direct_child(part->node, subtree)) { wlr_scene_node_set_position(part->node, width - SSD_BUTTON_WIDTH * 2, 0); - struct ssd_button *button = - node_ssd_button_from_node(part->node); - if (button->toggled) { - wlr_scene_node_set_enabled(button->normal, - !maximized); - wlr_scene_node_set_enabled(button->toggled, - maximized); - wlr_scene_node_set_enabled(button->hover, - false); - wlr_scene_node_set_enabled(button->toggled_hover, - false); - } } continue; case LAB_SSD_PART_CORNER_TOP_RIGHT: @@ -379,6 +393,14 @@ ssd_update_title(struct ssd *ssd) ssd_update_title_positions(ssd); } +static void +ssd_button_set_hover(struct ssd_button *button, bool enabled) +{ + assert(button); + wlr_scene_node_set_enabled(&button->hover_tree->node, enabled); + wlr_scene_node_set_enabled(&button->icon_tree->node, !enabled); +} + void ssd_update_button_hover(struct wlr_scene_node *node, struct ssd_hover_state *hover_state) @@ -391,33 +413,22 @@ ssd_update_button_hover(struct wlr_scene_node *node, struct node_descriptor *desc = node->data; if (desc->type == LAB_NODE_DESC_SSD_BUTTON) { button = node_ssd_button_from_node(node); - if (button->hover == hover_state->node) { + if (button == hover_state->button) { /* Cursor is still on the same button */ return; } } disable_old_hover: - if (hover_state->node) { - wlr_scene_node_set_enabled(hover_state->node, false); - if (hover_state->maximized == (int)hover_state->view->maximized - || hover_state->maximized == -1) { - wlr_scene_node_set_enabled(hover_state->old_node, true); - } + if (hover_state->button) { + ssd_button_set_hover(hover_state->button, false); hover_state->view = NULL; - hover_state->node = NULL; + hover_state->button = NULL; } if (button) { - bool maximized = button->view->maximized; - if (maximized && !button->toggled) { - maximized = false; - } - wlr_scene_node_set_enabled(maximized ? button->toggled_hover : button->hover, true); + ssd_button_set_hover(button, true); hover_state->view = button->view; - hover_state->node = maximized ? button->toggled_hover : button->hover; - hover_state->old_node = maximized ? button->toggled : button->normal; - hover_state->maximized = button->toggled ? (int)button->view->maximized : -1; - wlr_scene_node_set_enabled(maximized ? button->toggled : button->normal, false); + hover_state->button = button; } }