diff --git a/include/ssd-internal.h b/include/ssd-internal.h index 4b458263..eeb1300f 100644 --- a/include/ssd-internal.h +++ b/include/ssd-internal.h @@ -5,6 +5,7 @@ #include #include "common/macros.h" #include "ssd.h" +#include "view.h" #define FOR_EACH(tmp, ...) \ { \ @@ -17,7 +18,10 @@ struct ssd_button { struct view *view; enum ssd_part_type type; + struct wlr_scene_node *icon; struct wlr_scene_node *hover; + struct wlr_scene_node *alticon; + struct wlr_scene_node *althover; struct wlr_scene_node *background; struct wl_listener destroy; @@ -96,6 +100,8 @@ struct ssd_part { struct ssd_hover_state { struct view *view; struct wlr_scene_node *node; + struct wlr_scene_node *old_node; + enum view_axis maximized; }; struct wlr_buffer; @@ -115,7 +121,9 @@ struct ssd_part *add_scene_buffer( struct ssd_part *add_scene_button( struct wl_list *part_list, enum ssd_part_type type, struct wlr_scene_tree *parent, float *bg_color, - struct wlr_buffer *icon_buffer, struct wlr_buffer *hover_buffer, int x, struct view *view); + struct wlr_buffer *icon_buffer, struct wlr_buffer *hover_buffer, + struct wlr_buffer *alticon_buffer, struct wlr_buffer *althover_buffer, + int x, struct view *view); struct ssd_part *add_scene_button_corner( struct wl_list *part_list, enum ssd_part_type type, enum ssd_part_type corner_type, struct wlr_scene_tree *parent, diff --git a/include/theme.h b/include/theme.h index 6238b555..e814f451 100644 --- a/include/theme.h +++ b/include/theme.h @@ -79,21 +79,25 @@ struct theme { /* textures */ struct lab_data_buffer *button_close_active_unpressed; struct lab_data_buffer *button_maximize_active_unpressed; + struct lab_data_buffer *button_restore_active_unpressed; struct lab_data_buffer *button_iconify_active_unpressed; struct lab_data_buffer *button_menu_active_unpressed; struct lab_data_buffer *button_close_inactive_unpressed; struct lab_data_buffer *button_maximize_inactive_unpressed; + struct lab_data_buffer *button_restore_inactive_unpressed; struct lab_data_buffer *button_iconify_inactive_unpressed; struct lab_data_buffer *button_menu_inactive_unpressed; struct lab_data_buffer *button_close_active_hover; struct lab_data_buffer *button_maximize_active_hover; + struct lab_data_buffer *button_restore_active_hover; struct lab_data_buffer *button_iconify_active_hover; struct lab_data_buffer *button_menu_active_hover; struct lab_data_buffer *button_close_inactive_hover; struct lab_data_buffer *button_maximize_inactive_hover; + struct lab_data_buffer *button_restore_inactive_hover; struct lab_data_buffer *button_iconify_inactive_hover; struct lab_data_buffer *button_menu_inactive_hover; diff --git a/src/ssd/ssd_part.c b/src/ssd/ssd_part.c index 2b96aead..4fcc04f1 100644 --- a/src/ssd/ssd_part.c +++ b/src/ssd/ssd_part.c @@ -108,7 +108,7 @@ add_scene_button_corner(struct wl_list *part_list, enum ssd_part_type type, -offset_x, -rc.theme->border_width); /* Finally just put a usual theme button on top, using an invisible hitbox */ - add_scene_button(part_list, type, parent, invisible, icon_buffer, hover_buffer, 0, view); + add_scene_button(part_list, type, parent, invisible, icon_buffer, hover_buffer, NULL, NULL, 0, view); return button_root; } @@ -141,10 +141,10 @@ get_scale_box(struct wlr_buffer *buffer, double container_width, struct ssd_part * add_scene_button(struct wl_list *part_list, enum ssd_part_type type, struct wlr_scene_tree *parent, float *bg_color, - struct wlr_buffer *icon_buffer, struct wlr_buffer *hover_buffer, int x, struct view *view) + struct wlr_buffer *icon_buffer, struct wlr_buffer *hover_buffer, + struct wlr_buffer *alticon_buffer, struct wlr_buffer *althover_buffer, + int x, struct view *view) { - struct wlr_scene_node *hover; - struct ssd_part *button_root = add_scene_part(part_list, type); parent = wlr_scene_tree_create(parent); button_root->node = &parent->node; @@ -178,9 +178,34 @@ add_scene_button(struct wl_list *part_list, enum ssd_part_type type, wlr_scene_node_set_enabled(hover_part->node, false); + /* Alternate icon */ + struct ssd_part *alticon_part, *althover_part; + if (alticon_buffer) + { + alticon_part = add_scene_buffer(part_list, type, + parent, alticon_buffer, icon_geo.x, icon_geo.y); + + wlr_scene_buffer_set_dest_size( + wlr_scene_buffer_from_node(alticon_part->node), + icon_geo.width, icon_geo.height); + + wlr_scene_node_set_enabled(alticon_part->node, false); + + althover_part = add_scene_buffer(part_list, type, + parent, althover_buffer, hover_geo.x, hover_geo.y); + + wlr_scene_buffer_set_dest_size( + wlr_scene_buffer_from_node(althover_part->node), + hover_geo.width, hover_geo.height); + + wlr_scene_node_set_enabled(althover_part->node, false); + } struct ssd_button *button = ssd_button_descriptor_create(button_root->node); button->type = type; button->view = view; + button->icon = icon_part->node; + button->alticon = alticon_buffer ? alticon_part->node : NULL; + button->althover = alticon_buffer ? althover_part->node : NULL; button->hover = hover_part->node; button->background = bg_rect->node; return button_root; diff --git a/src/ssd/ssd_titlebar.c b/src/ssd/ssd_titlebar.c index 5e23bc71..02755581 100644 --- a/src/ssd/ssd_titlebar.c +++ b/src/ssd/ssd_titlebar.c @@ -34,11 +34,13 @@ ssd_titlebar_create(struct ssd *ssd) struct wlr_buffer *menu_button_unpressed; struct wlr_buffer *iconify_button_unpressed; struct wlr_buffer *maximize_button_unpressed; + struct wlr_buffer *restore_button_unpressed; struct wlr_buffer *close_button_unpressed; struct wlr_buffer *menu_button_hover; struct wlr_buffer *iconify_button_hover; struct wlr_buffer *maximize_button_hover; + struct wlr_buffer *restore_button_hover; struct wlr_buffer *close_button_hover; ssd->titlebar.tree = wlr_scene_tree_create(ssd->tree); @@ -56,10 +58,12 @@ ssd_titlebar_create(struct ssd *ssd) iconify_button_unpressed = &theme->button_iconify_active_unpressed->base; close_button_unpressed = &theme->button_close_active_unpressed->base; maximize_button_unpressed = &theme->button_maximize_active_unpressed->base; + restore_button_unpressed = &theme->button_restore_active_unpressed->base; menu_button_hover = &theme->button_menu_active_hover->base; iconify_button_hover = &theme->button_iconify_active_hover->base; close_button_hover = &theme->button_close_active_hover->base; maximize_button_hover = &theme->button_maximize_active_hover->base; + restore_button_hover = &theme->button_restore_active_hover->base; } else { color = theme->window_inactive_title_bg_color; corner_top_left = &theme->corner_top_left_inactive_normal->base; @@ -68,11 +72,13 @@ ssd_titlebar_create(struct ssd *ssd) iconify_button_unpressed = &theme->button_iconify_inactive_unpressed->base; maximize_button_unpressed = &theme->button_maximize_inactive_unpressed->base; + restore_button_unpressed = &theme->button_restore_inactive_unpressed->base; close_button_unpressed = &theme->button_close_inactive_unpressed->base; menu_button_hover = &theme->button_menu_inactive_hover->base; iconify_button_hover = &theme->button_iconify_inactive_hover->base; close_button_hover = &theme->button_close_inactive_hover->base; maximize_button_hover = &theme->button_maximize_inactive_hover->base; + restore_button_hover = &theme->button_restore_inactive_hover->base; wlr_scene_node_set_enabled(&parent->node, false); } wl_list_init(&subtree->parts); @@ -86,10 +92,11 @@ ssd_titlebar_create(struct ssd *ssd) LAB_SSD_BUTTON_WINDOW_MENU, LAB_SSD_PART_CORNER_TOP_LEFT, parent, corner_top_left, menu_button_unpressed, menu_button_hover, 0, view); add_scene_button(&subtree->parts, LAB_SSD_BUTTON_ICONIFY, parent, - color, iconify_button_unpressed, iconify_button_hover, + color, iconify_button_unpressed, iconify_button_hover, NULL, NULL, width - SSD_BUTTON_WIDTH * 3, view); add_scene_button(&subtree->parts, LAB_SSD_BUTTON_MAXIMIZE, parent, color, maximize_button_unpressed, maximize_button_hover, + restore_button_unpressed, restore_button_hover, width - SSD_BUTTON_WIDTH * 2, view); add_scene_button_corner(&subtree->parts, LAB_SSD_BUTTON_CLOSE, LAB_SSD_PART_CORNER_TOP_RIGHT, parent, @@ -172,10 +179,15 @@ ssd_titlebar_update(struct ssd *ssd) width - SSD_BUTTON_WIDTH * 3, 0); } continue; - case LAB_SSD_BUTTON_MAXIMIZE: + case LAB_SSD_BUTTON_MAXIMIZE: 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); + wlr_scene_node_set_enabled (button->icon, !maximized); + wlr_scene_node_set_enabled (button->alticon, maximized); + wlr_scene_node_set_enabled (button->hover, false); + wlr_scene_node_set_enabled (button->althover, false); } continue; case LAB_SSD_PART_CORNER_TOP_RIGHT: @@ -378,13 +390,20 @@ ssd_update_button_hover(struct wlr_scene_node *node, disable_old_hover: if (hover_state->node) { wlr_scene_node_set_enabled(hover_state->node, false); + if (hover_state->maximized == hover_state->view->maximized) + wlr_scene_node_set_enabled (hover_state->old_node, true); hover_state->view = NULL; hover_state->node = NULL; } if (button) { - wlr_scene_node_set_enabled(button->hover, true); + bool maximized = button->view->maximized; + if (maximized && !button->alticon) maximized = false; + wlr_scene_node_set_enabled (maximized ? button->althover : button->hover, true); hover_state->view = button->view; - hover_state->node = button->hover; + hover_state->node = maximized ? button->althover : button->hover; + hover_state->old_node = maximized ? button->alticon : button->icon; + hover_state->maximized = button->view->maximized; + wlr_scene_node_set_enabled (maximized ? button->alticon : button->icon, false); } } diff --git a/src/theme.c b/src/theme.c index 067b0b95..e80f4ec5 100644 --- a/src/theme.c +++ b/src/theme.c @@ -95,6 +95,18 @@ load_buttons(struct theme *theme) theme->window_inactive_button_max_unpressed_image_color, }, }, + { + "max_toggled", + { 0x3f, 0x3f, 0x21, 0x21, 0x21, 0x3f }, + { + &theme->button_restore_active_unpressed, + theme->window_active_button_max_unpressed_image_color, + }, + { + &theme->button_restore_inactive_unpressed, + theme->window_inactive_button_max_unpressed_image_color, + }, + }, { "close", { 0x33, 0x3f, 0x1e, 0x1e, 0x3f, 0x33 }, @@ -143,6 +155,18 @@ load_buttons(struct theme *theme) theme->window_inactive_button_max_unpressed_image_color, }, }, + { + "max_hover_toggled", + { 0x3f, 0x3f, 0x21, 0x21, 0x21, 0x3f }, + { + &theme->button_restore_active_hover, + theme->window_active_button_max_unpressed_image_color, + }, + { + &theme->button_restore_inactive_hover, + theme->window_inactive_button_max_unpressed_image_color, + }, + }, { "close_hover", { 0x33, 0x3f, 0x1e, 0x1e, 0x3f, 0x33 },