Skip to content

Classic menu: allow more than two columns, and choose which column has the second-pane look - #2580

Open
emilioheredia-source wants to merge 3 commits into
Open-Shell:masterfrom
emilioheredia-source:more-columns
Open

emilioheredia-source wants to merge 3 commits into
Open-Shell:masterfrom
emilioheredia-source:more-columns

Conversation

@emilioheredia-source

Copy link
Copy Markdown

This is the column work from #2544, which is what I set out to build; the earlier PRs were fixes I found along the way. As suggested there, it comes as separate PRs. This is 1 of 5:

# PR Builds on
1 More than two columns, and the Second pane look setting (this PR) master
2 A Pinned programs item, and rows per column for the pinned and recent lists 1
3 Recent Programs: Show as a list instead of a sub-menu master
4 A Heading item (a separator with a label) master
5 Column lines, and the same width for all columns 1

These changes let the Classic menu be laid out in as many columns as the user wants, with the pinned and recent programs placed where they like, so the menu can be as wide or as tall as they prefer. The pinned area of the Windows 10 Start menu is one example of a layout this allows; the difference from Windows 11 is that the size is up to the user, not fixed. Everything is built from what the menu already has: custom items, column breaks, separators and the skin's panes. With the default settings nothing changes. Similar layouts have been asked for since Classic Shell (forum, 2013) and again in #2473.

Where this is going. Not this PR: this needs all five. This PR adds the extra columns and the Second pane look setting; the pinned and recent lists in their own columns, the headings and the column lines come with PRs 2 to 5 (example programs, pinned and recent):

end goal

What this PR does on its own

In Classic with two columns, every column break now starts a column. The last one still starts the second pane, and earlier ones add columns to the first pane, so a menu with one break looks as before. The Windows 7 style keeps using only its first break.

A new setting on the Menu Look tab, Second pane look, picks which column gets the skin's second-pane look:

  • Last column (the default, as before)
  • None: all columns look alike, and column breaks only start new columns
  • First column: the first column gets it and is drawn on the left. The background is drawn as usual and then mirrored, so the skin's outer borders stay on the outside.

settings menu look

With this PR alone: the default menu, with Downloads, Music and Videos added to its places. Before, the right column (places and system together) sets the height and the first column has a gap. After, the same items with one more column break, between Recent Items and Settings: places and system get a column each, all three columns are about the same length, and the menu is about half as tall.

Before (as today) After: one more column break After, Second pane look = First column
before after after, first column

The layout assumed column 0 and column 1 in many places, so those now work per pane: each pane's width is the sum of its columns, items are offset from their own pane, every column is aligned to the bottom on its own (COLUMN_PADDING), the columns inside a pane get the skin's vertical separators like sub-menu columns do, and an item's icon size follows its pane.

The pager needed one fix too: it used the whole first pane as its column, which was the same thing with two columns. With more columns its arrows were drawn in the middle of the pane, and hovering or clicking at the top or bottom of any column hit the pager. It now covers only the first column, where the pinned programs are.

The tooltip of Column break in Customize Start Menu now says it starts another column.

Trying it

The zip has the three settings files used for the screenshots: Settings, Backup → Load from XML file. Loading one replaces all your settings, so save yours first with Backup → Save to XML file. Each is the default Classic with two columns menu with Downloads, Music and Videos added, and the Immersive skin with icons in the second pane: before-two-columns.xml as it is, after-three-columns.xml with one more COLUMN_BREAK, and after-three-columns-first.xml with Second pane look = First column as well. The pinned and recent programs are your own; the screenshots show two of each, so that the columns come out the same length.

settings-examples.zip

Tested

On Windows 11 26H2 (26300), x64, with the Immersive skin:

  • With one column break, the layout is the same as master's: I logged every item's position from both builds and the logs match. The same holds for the Windows 7 style and the single-column Classic style.
  • The three Second pane look values, with two and with three columns.
  • The pager with more pinned programs than fit: the arrows sit under the first column, hovering at the same height in another column doesn't scroll, and hovering on the arrow does. Scrolling with the wheel and the arrows, and clicking next to them, also work.
  • By hand, with three columns: sub-menus opened from the new columns, the keyboard across the columns, the search box, pinning and reordering by drag and drop, right-click menus, switching the three values in the settings, and First column with each skin that ships.
  • The full rebuild has no errors or warnings.

The screenshots were taken with #2575 applied too, so the pinned Store apps show their icons.

Every column break now starts a column. The last one still starts the
second pane, and earlier ones add columns to the first pane, so a menu
with one break looks exactly as before. The Windows 7 style keeps using
only its first break.

A new setting on the Menu Look tab, Second pane look, picks which column
gets the skin's second-pane look: the last column (the default, as
before), none (all columns alike), or the first column, drawn on the
left. For the first column the background is drawn as usual and then
mirrored, so the skin's outer borders stay on the outside; emblems, the
user picture and the user name are placed in their pane afterwards.

What had to change for that, since the layout assumed column 0 and
column 1 in many places: each pane's width is the sum of its columns,
items are offset from their own pane's content rectangle, every column
is aligned to the bottom on its own (COLUMN_PADDING), and the columns
inside a pane get the skin's vertical separators like sub-menu columns
do. The icon size of an item, which AddStandardItems picks before the
layout, follows the same panes: until now every item after the first
column break got the second pane's icon size, so a middle column lost
its icons with skins that hide them in the second pane.

The pager scrolls the first column, where the pinned programs are, and
until now it used the whole first pane for that, which was the same
thing. With more columns it is not: the arrows were drawn in the middle
of the pane, and hovering or clicking at the top or bottom of any column
of the pane hit the pager. GetScrollRect gives the pager its own column.
With Second pane look = First that column is in the second pane, whose
items can draw composited text (their own opacity setting). Composited
text ignores the clip rectangle, so the pager also checks those items
before it draws its background again over the spilled text.
The scroll range for touch, hover, keyboard and wheel scrolling was still
measured from the top of the first pane (m_rContent). With Second pane
look = First column the pinned programs are in the second pane, whose
top can be at another height, depending on the skin's padding, so the
last pinned program could be cut off or followed by a gap. It now comes
from GetScrollRect, like the rest of the pager. With Immersive both panes
start at the same height, so the screenshots in this PR don't change.
A drop on empty space adds the program to the pinned programs. It was
measured against the first pane (m_rContent), which until now was the
same as their column. With more columns, a drop on empty space in
another column of the first pane pinned the program too, and with
Second pane look = First column a drop in the pinned programs' own
column did nothing. It now uses GetScrollRect, like the pager.

The pager's scroll range was the same expression in six places;
GetScrollRange now gives it once.
@emilioheredia-source

Copy link
Copy Markdown
Author

I pushed two more commits, both found while preparing the next PR in the series. The first commit still measured two things against the first pane, which until now was the same as the column of the pinned programs:

  • The pager's scroll range for touch, hovering over the arrows, the keyboard and the mouse wheel. With Second pane look = First column the pinned programs are in the second pane, and with a skin that starts the two panes at different heights the last one could be cut off. It now comes from GetScrollRange, based on GetScrollRect like the rest of the pager.
  • A drop on empty space pinned the program anywhere in the first pane. Now it does so only in the pinned programs' column.

I kept them as separate commits so you only need to look at the new lines. With Immersive both panes start at the same height, so the screenshots stay the same.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant