[PATCH v5 weston] xwm: Choose icon closest to target size
Derek Foreman
derekf at osg.samsung.com
Thu Mar 29 13:25:52 UTC 2018
Since this is a little further from landing than I thought, as is the
scaling patch, I think the best move for the short term is to revert the
icon stuff entirely and move forward after the release.
Thanks,
Derek
On 2018-03-29 04:17 AM, Pekka Paalanen wrote:
> On Tue, 27 Mar 2018 12:43:36 -0500
> Derek Foreman <derekf at osg.samsung.com> wrote:
>
>> Xwayland clients can offer multiple icon sizes in no particular order.
>> Previously xwm was selecting the first one unconditionally. This patch
>> selects the icon that matches the size closest to the target size. The
>> target size is hard coded to 16 since there is only one theme and the
>> data used to create the theme is hard coded.
>>
>> Co-authored-by: Scott Moreau <oreaus at gmail.com>
>>
>
> Missing signed-off-by.
>
> Scott, are you happy with your attribution here?
>
>
>> ---
>>
>> Changed in v2:
>>
>> - Fix typo setting width to height
>>
>> Changed in v3:
>>
>> - Move checks for malformed input into data handling function
>>
>> Changed in v4:
>>
>> - #define XWM_ICON_SIZE in this patch and do not #undef it
>> - Start with first icon found before choosing icon\
>> - Check for NULL data in get_icon_size_from_data()
>>
>> Changed in v5:
>> - remove allocations, process in a single pass
>> - rebase on top of memory leak fix
>>
>> xwayland/window-manager.c | 51 ++++++++++++++++++++++++++++++++++++++++-------
>> 1 file changed, 44 insertions(+), 7 deletions(-)
>>
>> diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
>> index dad117fa..5209ac66 100644
>> --- a/xwayland/window-manager.c
>> +++ b/xwayland/window-manager.c
>> @@ -127,6 +127,8 @@ struct motif_wm_hints {
>> #define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 /* move via keyboard */
>> #define _NET_WM_MOVERESIZE_CANCEL 11 /* cancel operation */
>>
>> +#define XWM_ICON_SIZE 16 /* width and height of frame icon */
>> +
>> struct weston_output_weak_ref {
>> struct weston_output *output;
>> struct wl_listener destroy_listener;
>> @@ -1352,6 +1354,44 @@ weston_wm_window_schedule_repaint(struct weston_wm_window *window)
>> weston_wm_window_do_repaint, window);
>> }
>>
>> +static uint32_t *
>> +get_icon_size_from_data(int target_width, int target_height,
>> + uint32_t *width, uint32_t *height,
>> + uint32_t length, uint32_t *data)
>
> This may be a static function, but it really needs doxygen doc to
> explain all the arguments and return value, particularly for 'length',
> see below.
>
>> +{
>> + uint32_t *d = data, *ret = NULL, w, h;
>> + int a1, a2, a3;
>
> I'd really like better names than a1, a2, a3. There are so many
> variables in this function that they need descriptive names.
>
>> +
>> + if (!data)
>> + return NULL;
>> +
>> + /* Choose closest match by comparing icon dimension areas */
>> + a1 = target_width * target_height;
>> +
>> + *width = *height = 0;
>> +
>> + while (d - data < length / 4) {
>
> Maybe using
> uint32_t *end = data + length;
> would make this easier to read.
>
> Isn't length/4 wrong, because length is already in uint32_t units by
> the caller?
>
>> + w = *d++;
>> + h = *d++;
>> +
>> + /* Some checks against malformed input. */
>> + if (w == 0 || h == 0 || length < 2 + w * h)
>
> Checking against 'length' is incorrect, because we need to be checking
> against the remaining length, not against the whole length, as we may
> have skipped an icon alrady. Checking against 'end' would help here too.
>
>> + return ret;
>> +
>> + a2 = w * h;
>> + a3 = *width * *height;
>> + if (!a3 || abs(a2 - a1) < abs(a3 - a1)) {
>> + *width = w;
>> + *height = h;
>> + ret = d;
>> + }
>> +
>> + d += a2;
>
> The computations here seem to be correct.
>
>> + }
>> +
>> + return ret;
>> +}
>> +
>> static void
>> handle_icon_surface_destroy(void *data)
>> {
>> @@ -1367,9 +1407,6 @@ weston_wm_handle_icon(struct weston_wm *wm, struct weston_wm_window *window)
>> uint32_t *data, width, height;
>> cairo_surface_t *new_surface;
>>
>> - /* TODO: icons don’t have any specified order, we should pick the
>> - * closest one to the target dimension instead of the first one. */
>> -
>> cookie = xcb_get_property(wm->conn, 0, window->id,
>> wm->atom.net_wm_icon, XCB_ATOM_ANY, 0,
>> UINT32_MAX);
>
> Type is XCB_ATOM_ANY.
>
> The context here is missing to show this:
>
> reply = xcb_get_property_reply(wm->conn, cookie, NULL);
> length = xcb_get_property_value_length(reply);
>
> /* This is in 32-bit words, not in bytes. */
> if (length < 2) {
> free(reply);
> return;
> }
>
> data = xcb_get_property_value(reply);
>
> What are the units of 'length'?
>
> The comment here says words, but if you look at the example in 'man
> xcb_get_property', it is in bytes. If they are both right, then the
> length unit must depend on something.
>
> The type is not checked from the reply, and neither is 'format' checked
> from the reply. My wild guess would be that 'format' determines the
> units of 'length', and so it is controllable by the X11 client that set
> the property.
>
> I think weston_wm_window_read_properties() is equally very much broken
> against badly formatted properties, because it assumes a certain length
> from just the type or even atom name(!) without actually checking the
> length. dump_property() looks suspicious as well. It's probably
> everything that ever parses an xcb_get_property_reply_t in XWM.
>
> The EWMH spec may say that a certain property needs to have certain
> format and type, but I don't believe there is anything actually
> guaranteeing to follow the spec, so it's up to us to verify the data is
> proper.
>
>> @@ -1383,11 +1420,11 @@ weston_wm_handle_icon(struct weston_wm *wm, struct weston_wm_window *window)
>> }
>>
>> data = xcb_get_property_value(reply);
>> - width = *data++;
>> - height = *data++;
>>
>> - /* Some checks against malformed input. */
>> - if (width == 0 || height == 0 || length < 2 + width * height) {
>> + data = get_icon_size_from_data(XWM_ICON_SIZE, XWM_ICON_SIZE,
>> + &width, &height, length, data);
>> +
>> + if (!data) {
>> free(reply);
>> return;
>> }
>
> Thanks,
> pq
>
More information about the wayland-devel
mailing list