@@ -36,6 +36,7 @@ twin_window_t *twin_window_create(twin_screen_t *screen,
3636 window -> screen = screen ;
3737 window -> style = style ;
3838 window -> active = false;
39+ window -> iconify = false;
3940 switch (window -> style ) {
4041 case TwinWindowApplication :
4142 left = TWIN_BW ;
@@ -179,7 +180,7 @@ bool twin_window_valid_range(twin_window_t *window,
179180 y < window -> pixmap -> y + window -> pixmap -> height - offset_y ) {
180181 if (y < window -> pixmap -> y + (window -> client .top ))
181182 return !twin_pixmap_transparent (window -> pixmap , x , y );
182- return true ;
183+ return ! window -> iconify ;
183184 }
184185 return false;
185186 }
@@ -234,8 +235,8 @@ static void twin_window_frame(twin_window_t *window)
234235 twin_fixed_t text_width ;
235236 twin_fixed_t title_right ;
236237 twin_fixed_t close_x ;
237- twin_fixed_t max_x ;
238- twin_fixed_t min_x ;
238+ twin_fixed_t restore_x ;
239+ twin_fixed_t iconify_x ;
239240 twin_fixed_t resize_x ;
240241 twin_fixed_t resize_y ;
241242 const char * name ;
@@ -265,8 +266,8 @@ static void twin_window_frame(twin_window_t *window)
265266
266267
267268 close_x = c_right - t_arc_2 - icon_size ;
268- max_x = close_x - bw - icon_size ;
269- min_x = max_x - bw - icon_size ;
269+ restore_x = close_x - bw - icon_size ;
270+ iconify_x = restore_x - bw - icon_size ;
270271 resize_x = twin_int_to_fixed (window -> client .right );
271272 resize_y = twin_int_to_fixed (window -> client .bottom );
272273
@@ -314,14 +315,14 @@ static void twin_window_frame(twin_window_t *window)
314315 twin_icon_draw (pixmap , TwinIconMenu , m );
315316
316317 twin_matrix_identity (& m );
317- twin_matrix_translate (& m , min_x , icon_y );
318+ twin_matrix_translate (& m , iconify_x , icon_y );
318319 twin_matrix_scale (& m , icon_size , icon_size );
319- twin_icon_draw (pixmap , TwinIconMinimize , m );
320+ twin_icon_draw (pixmap , TwinIconIconify , m );
320321
321322 twin_matrix_identity (& m );
322- twin_matrix_translate (& m , max_x , icon_y );
323+ twin_matrix_translate (& m , restore_x , icon_y );
323324 twin_matrix_scale (& m , icon_size , icon_size );
324- twin_icon_draw (pixmap , TwinIconMaximize , m );
325+ twin_icon_draw (pixmap , TwinIconRestore , m );
325326
326327 twin_matrix_identity (& m );
327328 twin_matrix_translate (& m , close_x , icon_y );
@@ -494,21 +495,66 @@ bool twin_window_dispatch(twin_window_t *window, twin_event_t *event)
494495 twin_event_t ev = * event ;
495496 bool delegate = true;
496497
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 restore_x = close_x - bw - icon_size ;
521+ twin_fixed_t iconify_x = restore_x - bw - icon_size ;
522+ int local_x , local_y ;
523+
497524 switch (ev .kind ) {
498525 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 (iconify_x ) &&
530+ local_x < twin_fixed_to_int (restore_x )) {
531+ window -> iconify = 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 (restore_x ) &&
535+ local_x < twin_fixed_to_int (close_x )) {
536+ window -> iconify = false;
537+ twin_pixmap_damage (window -> pixmap , 0 , 0 , window -> pixmap -> width ,
538+ window -> pixmap -> height );
539+ }
540+ }
499541 case TwinEventActivate :
500542 /* Set window active. */
501543 /*
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 iconified window is inactive. When the box is triggered by
545+ * TwinEventButtonDown and the window is not iconified, 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.
504549 */
505- if (!window -> active ) {
550+ if (window -> iconify )
551+ window -> active = false;
552+ else
506553 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 );
512558 }
513559#if defined(CONFIG_DROP_SHADOW )
514560 /* Handle drop shadow. */
0 commit comments