From: Huw Campbell <huw.campbell@gmail.com> Also remove some obfuscation, stateWidth must be 0 for Icon mode, as there are no sub-items in Icon mode, it's just extra work and confusing. --- dlls/comctl32/listview.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index b83bad11680..0478e0f1524 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -2451,15 +2451,11 @@ static void LISTVIEW_GetItemMetrics(const LISTVIEW_INFO *infoPtr, const LVITEMW if (doIcon) { LONG state_width = 0; - - if (infoPtr->himlState && lpLVItem->iSubItem == 0) - state_width = infoPtr->iconStateSize.cx; - if (infoPtr->uView == LV_VIEW_ICON) { - Icon.left = Box.left + state_width; + Icon.left = Box.left; if (infoPtr->himlNormal) - Icon.left += (infoPtr->nItemWidth - infoPtr->iconSize.cx - state_width) / 2; + Icon.left += (infoPtr->nItemWidth - infoPtr->iconSize.cx) / 2; Icon.top = Box.top + ICON_TOP_PADDING; Icon.right = Icon.left; Icon.bottom = Icon.top; @@ -2469,9 +2465,9 @@ static void LISTVIEW_GetItemMetrics(const LISTVIEW_INFO *infoPtr, const LVITEMW Icon.bottom += infoPtr->iconSize.cy; } } - else if (lpLVItem->iSubItem == 0 && infoPtr->uView == LV_VIEW_TILE) + else if (infoPtr->uView == LV_VIEW_TILE) { - Icon.left = Box.left + state_width; + Icon.left = Box.left; Icon.top = Box.top; Icon.right = Icon.left; Icon.bottom = Icon.top; @@ -2483,6 +2479,9 @@ static void LISTVIEW_GetItemMetrics(const LISTVIEW_INFO *infoPtr, const LVITEMW } else /* LV_VIEW_SMALLICON, LV_VIEW_LIST or LV_VIEW_DETAILS */ { + if (infoPtr->himlState && lpLVItem->iSubItem == 0) + state_width = infoPtr->iconStateSize.cx; + Icon.left = Box.left + state_width; if (infoPtr->uView == LV_VIEW_DETAILS && lpLVItem->iSubItem == 0) @@ -4839,6 +4838,7 @@ static void LISTVIEW_DrawItemPart(LISTVIEW_INFO *infoPtr, LVITEMW *item, const N HIMAGELIST himl; UINT format; RECT *focus; + BOOL isTileSubitem = infoPtr->uView == LV_VIEW_TILE && item->iSubItem; /* now check if we need to update the focus rectangle */ focus = infoPtr->bFocus && (item->state & LVIS_FOCUSED) ? &infoPtr->rcFocus : 0; @@ -4871,7 +4871,7 @@ static void LISTVIEW_DrawItemPart(LISTVIEW_INFO *infoPtr, LVITEMW *item, const N /* in detail mode, we want to paint background for label rect when * item is not selected or listview has full row select; otherwise paint * background for text only */ - if ( infoPtr->uView == LV_VIEW_ICON || + if ( infoPtr->uView == LV_VIEW_ICON || isTileSubitem || (infoPtr->uView == LV_VIEW_DETAILS && (!(item->state & LVIS_SELECTED) || (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)))) background = &rcLabel; @@ -4907,6 +4907,10 @@ static void LISTVIEW_DrawItemPart(LISTVIEW_INFO *infoPtr, LVITEMW *item, const N } infoPtr->rcFocus = rcSelect; } + else if (isTileSubitem) + /* in tile mode the focus box wraps across all the labels; as the subitems are drawn after + * the main item, that means we can take a union here. */ + UnionRect(&infoPtr->rcFocus, &infoPtr->rcFocus, &rcLabel); else infoPtr->rcFocus = rcLabel; } @@ -4924,7 +4928,8 @@ static void LISTVIEW_DrawItemPart(LISTVIEW_INFO *infoPtr, LVITEMW *item, const N /* item icons */ himl = ((infoPtr->uView == LV_VIEW_ICON || infoPtr->uView == LV_VIEW_TILE) ? infoPtr->himlNormal : infoPtr->himlSmall); - if (himl && item->iImage >= 0 && !IsRectEmpty(&rcIcon)) + /* draw the icon if it exists and we're not the subitem in tile mode (the main item will draw it) */ + if (himl && item->iImage >= 0 && !IsRectEmpty(&rcIcon) && !isTileSubitem) { UINT style; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10191