On Wed, May 02, 2012 at 01:00:10AM +0200, Martin Minarik wrote:
> This provides basic icon and minimize, maximize, close buttons for window
> frame.

Very nice, thanks for looking into this.

> ----
> 
> diff --git a/clients/window.c b/clients/window.c
> index 2390485..790e849 100644
> --- a/clients/window.c
> +++ b/clients/window.c
> @@ -234,7 +234,11 @@ enum window_location {
>       WINDOW_RESIZING_MASK = 15,
>       WINDOW_EXTERIOR = 16,
>       WINDOW_TITLEBAR = 17,
> -     WINDOW_CLIENT_AREA = 18,
> +     WINDOW_TITLEBAR_ITEM_ICON = 18,
> +     WINDOW_TITLEBAR_ITEM_CLOSE = 19,
> +     WINDOW_TITLEBAR_ITEM_MAXIMIZE = 20,
> +     WINDOW_TITLEBAR_ITEM_MINIMIZE = 21,
> +     WINDOW_CLIENT_AREA = 22,
>  };
> 
>  const char *option_xkb_layout = "us";
> @@ -504,16 +508,16 @@ display_create_surface_from_file(struct display
> *display,
>       const char *filename;
>       int hotspot_x, hotspot_y;
>  } pointer_images[] = {
> -     { DATADIR "/weston/bottom_left_corner.png",      6, 30 },
> -     { DATADIR "/weston/bottom_right_corner.png",    28, 28 },
> -     { DATADIR "/weston/bottom_side.png",            16, 20 },
> +     { DATADIR "/weston/bottom_left_corner.png",      7, 25 },
> +     { DATADIR "/weston/bottom_right_corner.png",    25, 25 },
> +     { DATADIR "/weston/bottom_side.png",            16, 25 },
>       { DATADIR "/weston/grabbing.png",               20, 17 },
>       { DATADIR "/weston/left_ptr.png",               10,  5 },
> -     { DATADIR "/weston/left_side.png",              10, 20 },
> -     { DATADIR "/weston/right_side.png",             30, 19 },
> -     { DATADIR "/weston/top_left_corner.png",         8,  8 },
> -     { DATADIR "/weston/top_right_corner.png",       26,  8 },
> -     { DATADIR "/weston/top_side.png",               18,  8 },
> +     { DATADIR "/weston/left_side.png",               7, 16 },
> +     { DATADIR "/weston/right_side.png",             26, 16 },
> +     { DATADIR "/weston/top_left_corner.png",         6,  6 },
> +     { DATADIR "/weston/top_right_corner.png",       24,  6 },
> +     { DATADIR "/weston/top_side.png",               16,  5 },
>       { DATADIR "/weston/xterm.png",                  15, 15 },
>       { DATADIR "/weston/hand1.png",                  18, 11 }

What's up with these changes?  The hotspot location is take from the
DMZ theme, for example bottom_left_corner:

http://gitorious.org/opensuse/art/blobs/master/cursors/dmz/pngs/bottom_left_corner.in

for the 32x32 cursor, the hotspot there is 6,30.  Another good project
would be good to be parse Xcursor files instead of hardcoding a bunch
of pngs here.

>  };
> @@ -1017,9 +1021,25 @@ frame_redraw_handler(struct widget *widget, void
> *data)
>       cairo_t *cr;
>       cairo_text_extents_t extents;
>       cairo_surface_t *source;
> -     int x, y, width, height;
> +     int x, y, width, height, a;
>       struct window *window = widget->window;
> 
> +     cairo_surface_t* window_icon = cairo_image_surface_create_from_png(
> +             DATADIR "/weston/icon_window.png"
> +     );
> +
> +     cairo_surface_t* (sign[3]);
> +
> +     sign[0] = cairo_image_surface_create_from_png(
> +             DATADIR "/weston/sign_close.png"
> +     );
> +     sign[1] = cairo_image_surface_create_from_png(
> +             DATADIR "/weston/sign_maximize.png"
> +     );
> +     sign[2] = cairo_image_surface_create_from_png(
> +             DATADIR "/weston/sign_minimize.png"
> +     );
> +

We shouldn't be loading the pngs each in the rendering function.  Load
them up front in display_render_frame and keep the around like we do
with display->active_frame etc.  Having all that in struct display is
a bit of a hack, but we can fix that later.

>       if (window->type == TYPE_FULLSCREEN)
>               return;
> 
> @@ -1068,6 +1088,32 @@ frame_redraw_handler(struct widget *widget, void
> *data)
>               cairo_show_text(cr, window->title);
>       }
> 
> +     /* Window icon */
> +     cairo_set_source_surface(cr, window_icon,
> +              frame->margin+frame->width, frame->margin+frame->width);
> +     cairo_paint(cr);
> +
> +     /* 3 window buttons, 25x14 pixels */
> +     cairo_set_line_width(cr, 1);
> +
> +     for (a=0; a<3; a++){
> +             unsigned int x,y;
> +
> +             x=width - frame->margin - frame->width - (a+1)*25 - a*6-2;
> +             y=frame->margin+frame->width+1;

Please follow the code style and add spaces around operators, that is,
do this instead:

        y = frame->margin + frame->width + 1;

etc.

> +             cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
> +             cairo_rectangle (cr, x, y, 25, 14);
> +
> +             cairo_stroke_preserve(cr);
> +             cairo_set_source_rgb(cr, 0.9, 0.9, 0.9);
> +             cairo_fill (cr);
> +
> +             cairo_set_source_surface(cr, sign[a],
> +                      x+6, y+1);
> +             cairo_paint(cr);
> +     }
> +
>       cairo_destroy(cr);
>  }
> 
> @@ -1108,6 +1154,20 @@ frame_get_pointer_location(struct frame *frame,
> int32_t x, int32_t y)
>       else if (location == WINDOW_INTERIOR)
>               location = WINDOW_CLIENT_AREA;
> 
> +     /* Find icon or buttons in titlebar */
> +     if (location==WINDOW_TITLEBAR)
> +     if (x <= 16 + frame->margin + frame->width)
> +             location=WINDOW_TITLEBAR_ITEM_ICON;
> +     else if ((x > widget->allocation.width - frame->margin - frame->width -
> 27) &&
> +              (x <= widget->allocation.width - frame->margin - frame->width))
> +             location=WINDOW_TITLEBAR_ITEM_CLOSE;
> +     else if ((x > widget->allocation.width - frame->margin - frame->width -
> 2*27 - 5) &&
> +              (x <= widget->allocation.width - frame->margin - frame->width 
> - 27 - 5))
> +             location=WINDOW_TITLEBAR_ITEM_MAXIMIZE;
> +     else if ((x > widget->allocation.width - frame->margin - frame->width -
> 3*27 - 10) &&
> +              (x <= widget->allocation.width - frame->margin - frame->width 
> - 2*27 -
> 10))
> +             location=WINDOW_TITLEBAR_ITEM_MINIMIZE;
> +

We should make the buttons widgets instead extending this ad-hoc hack.
Creating the buttons as widgets give you enter/leave events so you can
highlight the buttons and get button events in a callback.  Call
widget_add_widget(frame, button_data) to add a sub-widget to the frame
widget, then set button and redraw handlers to implement painting and
button click handling.

>       return location;
>  }
> 
> @@ -1216,6 +1276,24 @@ frame_button_handler(struct widget *widget,
>                                             input_get_input_device(input),
>                                             display->serial);
>                       break;
> +             case WINDOW_TITLEBAR_ITEM_ICON:
> +                     window_show_frame_menu(window, input, time);
> +                     break;
> +             case WINDOW_TITLEBAR_ITEM_MINIMIZE:
> +                     fprintf(stderr,"Minimize\n");
> +                     /* TODO: Minimize */
> +                     break;
> +             case WINDOW_TITLEBAR_ITEM_MAXIMIZE:
> +                     fprintf(stderr,"Maximize\n");
> +                     /* TODO: Maximize */
> +                     break;

We do have a maximize request in wl_shell_surface you should use here.

> +             case WINDOW_TITLEBAR_ITEM_CLOSE:
> +                     if (window->close_handler)
> +                             window->close_handler(window->parent,
> +                                                   window->user_data);
> +                     else
> +                             display_exit(window->display);
> +                     break;

All these cases should just be widget button callbacks.

>               case WINDOW_RESIZING_TOP:
>               case WINDOW_RESIZING_BOTTOM:
>               case WINDOW_RESIZING_LEFT:
> @@ -1260,9 +1338,9 @@ frame_create(struct window *window, void *data)
>       frame->widget = window_add_widget(window, frame);
>       frame->child = widget_add_widget(frame->widget, data);
>       frame->margin = 32;
> -     frame->width = 4;
> -     frame->titlebar_height = 30
> -;
> +     frame->width = 6;
> +     frame->titlebar_height = 27;
> +
>       widget_set_redraw_handler(frame->widget, frame_redraw_handler);
>       widget_set_resize_handler(frame->widget, frame_resize_handler);
>       widget_set_enter_handler(frame->widget, frame_enter_handler);
> diff --git a/data/Makefile.am b/data/Makefile.am
> index 39b62ff..f789ad1 100644
> --- a/data/Makefile.am
> +++ b/data/Makefile.am
> @@ -1,6 +1,10 @@
>  westondatadir = $(datadir)/weston
> 
>  dist_westondata_DATA =                               \
> +     icon_window.png                         \
> +     sign_close.png                          \
> +     sign_maximize.png                       \
> +     sign_minimize.png                       \
>       bottom_left_corner.png                  \
>       bottom_right_corner.png                 \
>       bottom_side.png                         \

If you send the patch with git send-email, git will encode the pngs
and include them in the patch.

Kristian
_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to