yutani: window minimization, first pass
This commit is contained in:
parent
534aca26de
commit
2a18c192e4
@ -61,6 +61,8 @@ static void notify_subscribers(yutani_globals_t * yg);
|
||||
static void mouse_stop_drag(yutani_globals_t * yg);
|
||||
static void window_move(yutani_globals_t * yg, yutani_server_window_t * window, int x, int y);
|
||||
static yutani_server_window_t * top_at(yutani_globals_t * yg, uint16_t x, uint16_t y);
|
||||
static void window_unminimize(yutani_globals_t * yg, yutani_server_window_t * window);
|
||||
static void window_finish_minimize(yutani_globals_t * yg, yutani_server_window_t * w);
|
||||
|
||||
#define ENABLE_BLUR_BEHIND
|
||||
#ifdef ENABLE_BLUR_BEHIND
|
||||
@ -256,6 +258,7 @@ static void unorder_window(yutani_globals_t * yg, yutani_server_window_t * w) {
|
||||
}
|
||||
|
||||
list_t * zorder_owner = window_zorder_owner(yg, index);
|
||||
if (!zorder_owner) return;
|
||||
node_t * n = list_find(zorder_owner, w);
|
||||
if (!n) return;
|
||||
list_delete(zorder_owner, n);
|
||||
@ -324,6 +327,10 @@ static void set_focused_window(yutani_globals_t * yg, yutani_server_window_t * w
|
||||
return; /* Already focused */
|
||||
}
|
||||
|
||||
if (w->minimized) {
|
||||
window_unminimize(yg,w);
|
||||
}
|
||||
|
||||
if (yg->focused_window) {
|
||||
/* Send focus change to old focused window */
|
||||
yutani_msg_buildx_window_focus_change_alloc(response);
|
||||
@ -412,6 +419,7 @@ static yutani_server_window_t * server_window_create(yutani_globals_t * yg, int
|
||||
win->server_flags = flags;
|
||||
win->opacity = 255;
|
||||
win->hidden = 1;
|
||||
win->minimized = 0;
|
||||
|
||||
char key[1024];
|
||||
YUTANI_SHMKEY(yg->server_ident, key, 1024, win);
|
||||
@ -618,8 +626,7 @@ static void draw_cursor(yutani_globals_t * yg, int x, int y, int cursor) {
|
||||
* around the cursor, but it is relatively slow.
|
||||
*/
|
||||
static yutani_server_window_t * check_top_at(yutani_globals_t * yg, yutani_server_window_t * w, uint16_t x, uint16_t y){
|
||||
if (!w) return NULL;
|
||||
if (w->hidden) return NULL;
|
||||
if (!w || w->hidden || w->minimized) return NULL;
|
||||
int32_t _x = -1, _y = -1;
|
||||
yutani_device_to_window(w, x, y, &_x, &_y);
|
||||
if (_x < 0 || _x >= w->width || _y < 0 || _y >= w->height) return NULL;
|
||||
@ -726,7 +733,7 @@ static inline int matrix_is_translation(gfx_matrix_t m) {
|
||||
*/
|
||||
static int yutani_blit_window(yutani_globals_t * yg, yutani_server_window_t * window, int x, int y) {
|
||||
|
||||
if (window->hidden) {
|
||||
if (window->hidden || window->minimized) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -777,6 +784,10 @@ static int yutani_blit_window(yutani_globals_t * yg, yutani_server_window_t * wi
|
||||
list_insert(yg->windows_to_remove, window);
|
||||
return 0;
|
||||
}
|
||||
if (yutani_is_minimizing_animation[window->anim_mode]) {
|
||||
list_insert(yg->windows_to_minimize, window);
|
||||
return 0;
|
||||
}
|
||||
window->anim_mode = 0;
|
||||
window->anim_start = 0;
|
||||
} else {
|
||||
@ -808,6 +819,20 @@ static int yutani_blit_window(yutani_globals_t * yg, yutani_server_window_t * wi
|
||||
}
|
||||
}
|
||||
break;
|
||||
case YUTANI_EFFECT_MINIMIZE:
|
||||
{
|
||||
frame = yutani_animation_lengths[window->anim_mode] - frame;
|
||||
} /* fallthrough */
|
||||
case YUTANI_EFFECT_UNMINIMIZE:
|
||||
{
|
||||
double time_diff = ((double)frame / (float)yutani_animation_lengths[window->anim_mode]);
|
||||
double x = 0.5 + time_diff * 0.5;
|
||||
opacity *= time_diff;
|
||||
//int t_x = (window->width * (1.0 - x)) / 2;
|
||||
//gfx_matrix_translate(m, t_x, 0.0);
|
||||
gfx_matrix_scale(m, 1.0, x);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -882,7 +907,7 @@ static void yutani_post_vbox_rects(yutani_globals_t * yg) {
|
||||
|
||||
struct Rect * rects = (struct Rect *)(tmp+sizeof(int32_t));
|
||||
|
||||
#define DO_WINDOW(win) if (win && !win->hidden && *count < 255 ) { \
|
||||
#define DO_WINDOW(win) if (win && !win->hidden && !win->minimized && *count < 255 ) { \
|
||||
rects->x = (win)->x; \
|
||||
rects->y = (win)->y; \
|
||||
rects->xe = (win)->x + (win)->width; \
|
||||
@ -1277,6 +1302,13 @@ static void redraw_windows(yutani_globals_t * yg) {
|
||||
free(node);
|
||||
}
|
||||
|
||||
while (yg->windows_to_minimize->tail) {
|
||||
node_t * node = list_pop(yg->windows_to_minimize);
|
||||
window_finish_minimize(yg, node->value);
|
||||
free(node);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (yg->screenshot_frame) {
|
||||
@ -1392,6 +1424,27 @@ static void window_remove_from_client(yutani_globals_t * yg, yutani_server_windo
|
||||
}
|
||||
}
|
||||
|
||||
static void window_finish_minimize(yutani_globals_t * yg, yutani_server_window_t * w) {
|
||||
if (w->minimized) return;
|
||||
w->minimized = 1;
|
||||
w->anim_mode = 0;
|
||||
w->anim_start = 0;
|
||||
|
||||
unorder_window(yg,w);
|
||||
if (w == yg->focused_window) {
|
||||
yg->focused_window = NULL;
|
||||
if (yg->menu_zs->tail && yg->menu_zs->tail->value) {
|
||||
set_focused_window(yg, yg->menu_zs->tail->value);
|
||||
} else if (yg->mid_zs->tail && yg->mid_zs->tail->value) {
|
||||
set_focused_window(yg, yg->mid_zs->tail->value);
|
||||
}
|
||||
}
|
||||
|
||||
list_insert(yg->minimized_zs, w);
|
||||
|
||||
notify_subscribers(yg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually remove a window and free the associated resources.
|
||||
*/
|
||||
@ -1445,6 +1498,9 @@ static uint32_t ad_flags(yutani_globals_t * yg, yutani_server_window_t * win) {
|
||||
if (win == yg->focused_window) {
|
||||
flags |= 1;
|
||||
}
|
||||
if (win->minimized) {
|
||||
flags |= 2;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
@ -1584,6 +1640,28 @@ static void window_reveal(yutani_globals_t * yg, yutani_server_window_t * window
|
||||
window->anim_start = yutani_current_time(yg);
|
||||
}
|
||||
|
||||
static void window_unminimize(yutani_globals_t * yg, yutani_server_window_t * window) {
|
||||
if (!window->minimized) return;
|
||||
|
||||
node_t * n = list_find(yg->minimized_zs, window);
|
||||
if (n) {
|
||||
list_delete(yg->minimized_zs, n);
|
||||
free(n);
|
||||
}
|
||||
|
||||
list_insert(yg->mid_zs, window);
|
||||
window->z = 1;
|
||||
|
||||
window->minimized = 0;
|
||||
window->anim_mode = YUTANI_EFFECT_UNMINIMIZE; //yutani_pick_animation(window->server_flags, 0);
|
||||
window->anim_start = yutani_current_time(yg);
|
||||
}
|
||||
|
||||
static void window_minimize(yutani_globals_t * yg, yutani_server_window_t * window) {
|
||||
window->anim_mode = YUTANI_EFFECT_MINIMIZE; //yutani_pick_animation(window->server_flags, 0);
|
||||
window->anim_start = yutani_current_time(yg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a key event.
|
||||
*
|
||||
@ -1622,6 +1700,12 @@ static void handle_key_event(yutani_globals_t * yg, struct yutani_msg_key_event
|
||||
mark_window(yg,focused);
|
||||
return;
|
||||
}
|
||||
if ((ke->event.action == KEY_ACTION_DOWN) &&
|
||||
(ke->event.modifiers & KEY_MOD_LEFT_SUPER) &&
|
||||
(ke->event.keycode == 'a')) {
|
||||
window_minimize(yg,focused);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if ((ke->event.action == KEY_ACTION_DOWN) &&
|
||||
(ke->event.modifiers & KEY_MOD_LEFT_ALT) &&
|
||||
@ -2371,6 +2455,8 @@ int main(int argc, char * argv[]) {
|
||||
yg->menu_zs = list_create();
|
||||
yg->overlay_zs = list_create();
|
||||
yg->windows_to_remove = list_create();
|
||||
yg->windows_to_minimize = list_create();
|
||||
yg->minimized_zs = list_create();
|
||||
|
||||
yg->window_subscribers = list_create();
|
||||
|
||||
@ -2734,6 +2820,9 @@ int main(int argc, char * argv[]) {
|
||||
break;
|
||||
case YUTANI_MSG_QUERY_WINDOWS:
|
||||
{
|
||||
foreach (node, yg->minimized_zs) {
|
||||
yutani_query_result(yg, p->source, node->value);
|
||||
}
|
||||
yutani_query_result(yg, p->source, yg->bottom_z);
|
||||
foreach (node, yg->mid_zs) {
|
||||
yutani_query_result(yg, p->source, node->value);
|
||||
@ -2897,6 +2986,11 @@ int main(int argc, char * argv[]) {
|
||||
pex_send(yg->server, w->owner, response->size, (char *)response);
|
||||
}
|
||||
break;
|
||||
case YUTANI_SPECIAL_REQUEST_MINIMIZE:
|
||||
if (w) {
|
||||
window_minimize(yg,w);
|
||||
}
|
||||
break;
|
||||
case YUTANI_SPECIAL_REQUEST_CLIPBOARD:
|
||||
{
|
||||
yutani_msg_buildx_clipboard_alloc(response, yg->clipboard_size);
|
||||
|
@ -66,6 +66,7 @@ extern yutani_window_t * decor_show_default_menu(yutani_window_t * window, int y
|
||||
#define DECOR_RESIZE 3 /* Resize button */
|
||||
#define DECOR_MAXIMIZE 4
|
||||
#define DECOR_RIGHT 5
|
||||
#define DECOR_MINIMIZE 6
|
||||
|
||||
#define DECOR_ACTIVE 0
|
||||
#define DECOR_INACTIVE 1
|
||||
|
@ -61,8 +61,8 @@ static int yutani_animation_lengths[] = {
|
||||
0, /* None */
|
||||
200, /* Fade In */
|
||||
200, /* Fade Out */
|
||||
0, /* Minimize */
|
||||
0, /* Unminimized */
|
||||
200, /* Minimize */
|
||||
200, /* Unminimized */
|
||||
100, /* Squeeze in */
|
||||
100, /* Squeeze out */
|
||||
10, /* Disappear */
|
||||
@ -79,6 +79,17 @@ static int yutani_is_closing_animation[] = {
|
||||
1,
|
||||
};
|
||||
|
||||
static int yutani_is_minimizing_animation[] = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
/* Debug Options */
|
||||
#define YUTANI_DEBUG_WINDOW_BOUNDS 1
|
||||
#define YUTANI_DEBUG_WINDOW_SHAPES 1
|
||||
@ -161,6 +172,7 @@ typedef struct YutaniServerWindow {
|
||||
|
||||
/* Window is hidden? */
|
||||
int hidden;
|
||||
int minimized;
|
||||
} yutani_server_window_t;
|
||||
|
||||
typedef struct YutaniGlobals {
|
||||
@ -312,6 +324,9 @@ typedef struct YutaniGlobals {
|
||||
uint64_t resize_release_time;
|
||||
int32_t resizing_init_w;
|
||||
int32_t resizing_init_h;
|
||||
|
||||
list_t * windows_to_minimize;
|
||||
list_t * minimized_zs;
|
||||
} yutani_globals_t;
|
||||
|
||||
struct key_bind {
|
||||
|
@ -488,6 +488,7 @@ struct yutani_msg_clipboard {
|
||||
*/
|
||||
#define YUTANI_SPECIAL_REQUEST_MAXIMIZE 1
|
||||
#define YUTANI_SPECIAL_REQUEST_PLEASE_CLOSE 2
|
||||
#define YUTANI_SPECIAL_REQUEST_MINIMIZE 3
|
||||
|
||||
#define YUTANI_SPECIAL_REQUEST_CLIPBOARD 10
|
||||
|
||||
|
BIN
base/usr/share/ttk/fancy/button-minimize.png
Normal file
BIN
base/usr/share/ttk/fancy/button-minimize.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 502 B |
@ -44,9 +44,10 @@ static struct TT_Font * _tt_font = NULL;
|
||||
|
||||
#define BUTTON_CLOSE 0
|
||||
#define BUTTON_MAXIMIZE 1
|
||||
#define ACTIVE 2
|
||||
#define INACTIVE 11
|
||||
static sprite_t * sprites[20];
|
||||
#define BUTTON_MINIMIZE 2
|
||||
#define ACTIVE 3
|
||||
#define INACTIVE 12
|
||||
static sprite_t * sprites[21];
|
||||
|
||||
#define TEXT_OFFSET ((window->decorator_flags & DECOR_FLAG_TILED) ? 5 : 10)
|
||||
#define BUTTON_OFFSET ((window->decorator_flags & DECOR_FLAG_TILED) ? 5 : 0)
|
||||
@ -247,6 +248,12 @@ static void render_decorations_fancy(yutani_window_t * window, gfx_context_t * c
|
||||
draw_sprite_alpha_paint(ctx, sprites[BUTTON_MAXIMIZE],
|
||||
width + (BUTTON_OFFSET - 50) * TOTAL_SCALE,
|
||||
(16 - BUTTON_OFFSET) * TOTAL_SCALE, 1.0, title_color);
|
||||
|
||||
if (width + (BUTTON_OFFSET - 72) * TOTAL_SCALE > bounds.left_width) {
|
||||
draw_sprite_alpha_paint(ctx, sprites[BUTTON_MINIMIZE],
|
||||
width + (BUTTON_OFFSET - 72) * TOTAL_SCALE,
|
||||
(16 - BUTTON_OFFSET) * TOTAL_SCALE, 1.0, title_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -265,6 +272,12 @@ static int check_button_press_fancy(yutani_window_t * window, int x, int y) {
|
||||
y >= 16 * TOTAL_SCALE && y <= 26 * TOTAL_SCALE) {
|
||||
return DECOR_MAXIMIZE;
|
||||
}
|
||||
|
||||
if (x >= (int)window->width + (BUTTON_OFFSET - 72) * TOTAL_SCALE &&
|
||||
x <= (int)window->width + (BUTTON_OFFSET - 62) * TOTAL_SCALE &&
|
||||
y >= 16 * TOTAL_SCALE && y <= 26 * TOTAL_SCALE) {
|
||||
return DECOR_MINIMIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -273,6 +286,7 @@ static int check_button_press_fancy(yutani_window_t * window, int x, int y) {
|
||||
void decor_init() {
|
||||
init_sprite(BUTTON_CLOSE, TTK_FANCY_PATH "button-close.png");
|
||||
init_sprite(BUTTON_MAXIMIZE, TTK_FANCY_PATH "button-maximize.png");
|
||||
init_sprite(BUTTON_MINIMIZE, TTK_FANCY_PATH "button-minimize.png");
|
||||
|
||||
create_borders_from_spritesheet(ACTIVE, TTK_FANCY_PATH "borders-active.png");
|
||||
create_borders_from_spritesheet(INACTIVE, TTK_FANCY_PATH "borders-inactive.png");
|
||||
|
@ -122,6 +122,10 @@ static void _decor_maximize(yutani_t * yctx, yutani_window_t * window) {
|
||||
}
|
||||
}
|
||||
|
||||
static void _decor_minimize(yutani_t * yctx, yutani_window_t * window) {
|
||||
yutani_special_request(yctx, window, YUTANI_SPECIAL_REQUEST_MINIMIZE);
|
||||
}
|
||||
|
||||
static yutani_window_t * _decor_menu_owner_window = NULL;
|
||||
static struct MenuList * _decor_menu = NULL;
|
||||
|
||||
@ -320,6 +324,9 @@ int decor_handle_event(yutani_t * yctx, yutani_msg_t * m) {
|
||||
case DECOR_MAXIMIZE:
|
||||
_decor_maximize(yctx, window);
|
||||
break;
|
||||
case DECOR_MINIMIZE:
|
||||
_decor_minimize(yctx, window);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -79,13 +79,18 @@ static int widget_draw_windowlist(struct PanelWidget * this, gfx_context_t * ctx
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t text_color = TEXT_COLOR;
|
||||
if (j == focused_app) text_color = HILIGHT_COLOR;
|
||||
else if (ad->flags & 1) text_color = FOCUS_COLOR;
|
||||
else if (ad->flags & 2) text_color = premultiply(rgba(_RED(TEXT_COLOR),_GRE(TEXT_COLOR),_BLU(TEXT_COLOR),127));
|
||||
|
||||
if (title_width >= MIN_TEXT_WIDTH) {
|
||||
/* Ellipsifiy the title */
|
||||
char * s = ellipsify(ad->name, 14, font, title_width - 4, NULL);
|
||||
sprite_t * icon = icon_get_48(ad->icon);
|
||||
gfx_context_t * subctx = init_graphics_subregion(ctx, i, 0, w, ctx->height);
|
||||
draw_sprite_scaled_alpha(subctx, icon, w - 48 - 2, 0, 48, 48, (ad->flags & 1) ? 1.0 : 0.7);
|
||||
tt_draw_string_shadow(subctx, font, s, 14, 2, TEXT_Y_OFFSET, (j == focused_app) ? HILIGHT_COLOR : (ad->flags & 1) ? FOCUS_COLOR : TEXT_COLOR, rgb(0,0,0), 4);
|
||||
tt_draw_string_shadow(subctx, font, s, 14, 2, TEXT_Y_OFFSET, text_color, rgb(0,0,0), 4);
|
||||
free(subctx);
|
||||
free(s);
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user