@@ -36,6 +36,7 @@ twin_window_t *twin_window_create(twin_screen_t *screen,
36
36
window -> screen = screen ;
37
37
window -> style = style ;
38
38
window -> active = false;
39
+ window -> minimize = false;
39
40
switch (window -> style ) {
40
41
case TwinWindowApplication :
41
42
left = TWIN_BW ;
@@ -179,7 +180,7 @@ bool twin_window_valid_range(twin_window_t *window,
179
180
y < window -> pixmap -> y + window -> pixmap -> height - offset_y ) {
180
181
if (y < window -> pixmap -> y + (window -> client .top ))
181
182
return !twin_pixmap_transparent (window -> pixmap , x , y );
182
- return true ;
183
+ return ! window -> minimize ;
183
184
}
184
185
return false;
185
186
}
@@ -494,21 +495,66 @@ bool twin_window_dispatch(twin_window_t *window, twin_event_t *event)
494
495
twin_event_t ev = * event ;
495
496
bool delegate = true;
496
497
498
+ twin_fixed_t bw = twin_int_to_fixed (TWIN_TITLE_BW );
499
+ twin_fixed_t t_h = twin_int_to_fixed (window -> client .top ) - bw ;
500
+ twin_fixed_t t_arc_2 = t_h * 2 / 3 ;
501
+ twin_fixed_t c_right = twin_int_to_fixed (window -> client .right ) - bw / 2 ;
502
+ twin_fixed_t name_height = t_h - bw - bw / 2 ;
503
+ twin_fixed_t icon_size = name_height * 8 / 10 ;
504
+ twin_fixed_t menu_x = t_arc_2 ;
505
+ twin_fixed_t text_x = menu_x + icon_size + bw ;
506
+ twin_fixed_t text_width ;
507
+ twin_fixed_t title_right ;
508
+ twin_path_t * path = twin_path_create ();
509
+ const char * name = window -> name ;
510
+
511
+ text_width = twin_width_utf8 (path , name );
512
+ twin_path_destroy (path );
513
+ title_right = (text_x + text_width + bw + icon_size + bw + icon_size + bw +
514
+ icon_size + t_arc_2 );
515
+
516
+ if (title_right < c_right )
517
+ c_right = title_right ;
518
+
519
+ twin_fixed_t close_x = c_right - t_arc_2 - icon_size ;
520
+ twin_fixed_t max_x = close_x - bw - icon_size ;
521
+ twin_fixed_t min_x = max_x - bw - icon_size ;
522
+ int local_x , local_y ;
523
+
497
524
switch (ev .kind ) {
498
525
case TwinEventButtonDown :
526
+ local_y = ev .u .pointer .screen_y - window -> pixmap -> y ;
527
+ if (local_y >= 0 && local_y <= TWIN_BW + TWIN_TITLE_HEIGHT + TWIN_BW ) {
528
+ local_x = ev .u .pointer .screen_x - window -> pixmap -> x ;
529
+ if (local_x > twin_fixed_to_int (min_x ) &&
530
+ local_x < twin_fixed_to_int (max_x )) {
531
+ window -> minimize = true;
532
+ twin_pixmap_damage (window -> pixmap , 0 , 0 , window -> pixmap -> width ,
533
+ window -> pixmap -> height );
534
+ } else if (local_x > twin_fixed_to_int (max_x ) &&
535
+ local_x < twin_fixed_to_int (close_x )) {
536
+ window -> minimize = false;
537
+ twin_pixmap_damage (window -> pixmap , 0 , 0 , window -> pixmap -> width ,
538
+ window -> pixmap -> height );
539
+ }
540
+ }
499
541
case TwinEventActivate :
500
542
/* Set window active. */
501
543
/*
502
- * When the box is trigger by TwinEventButtonDown, its window's title
503
- * bar needs to change color and be put onto the toppest layer.
544
+ * A minimized window is inactive. When the box is triggered by
545
+ * TwinEventButtonDown and the window is not minimized, it becomes
546
+ * active. For a window to be considered active, it must be the topmost
547
+ * window on the screen. The window's title bar turns blue to indicate
548
+ * the active state.
504
549
*/
505
- if (!window -> active ) {
550
+ if (window -> minimize )
551
+ window -> active = false;
552
+ else
506
553
window -> active = true;
507
- twin_window_frame (window );
508
- if (window != window -> screen -> top -> window ) {
509
- window -> screen -> top -> window -> active = false;
510
- twin_window_frame (window -> screen -> top -> window );
511
- }
554
+ twin_window_frame (window );
555
+ if (window != window -> screen -> top -> window ) {
556
+ window -> screen -> top -> window -> active = false;
557
+ twin_window_frame (window -> screen -> top -> window );
512
558
}
513
559
#if defined(CONFIG_DROP_SHADOW )
514
560
/* Handle drop shadow. */
0 commit comments