Page MenuHome

UI: Windows Shell Links & Improved Mac Aliases
ClosedPublic

Authored by Harley Acheson (harley) on Apr 8 2020, 11:50 PM.
Tokens
"Like" token, awarded by Fracture128."Love" token, awarded by kryp."Love" token, awarded by Tetone."Like" token, awarded by Blendify."Like" token, awarded by Leroy."Like" token, awarded by EAW."Like" token, awarded by TheRedWaxPolice.

Details

Summary

Windows Shell Links

For Windows users the File Manager now supports many complex file system redirections like hard and soft links, mount points, etc. But one thing not supported is "Windows Shell Links". These are the oldest and easiest types of links to make in Windows. We have had requests to support these for more than a decade. For example, you can copy any file system item to the clipboard and then "paste shortcut" to make a file system item that redirects to that item. Once this patch is applied any valid shortcut files will no longer show their ".lnk" extension, just like in Windows Explorer, and use can use them in File Browser as expected.

Mac Alias Changes

Currently Mac alias support is limited to supporting aliases to folders. This patch allows aliases to blend files - for opening or appending - and for aliases to drives, files, images, videos, etc.

Display Changes*

Currently we are showing all folders that are symlinks or aliases with big arrow inside:

However this is a bit limiting. It cannot indicate any other information about the folder besides this one attribute. And this cannot be applied to links to documents. So this patch changes the "link" indicator to a smaller arrow at the bottom-left. This means we can indicate that an item is a link/alias/shortcut while also showing other information. Following are various different types of links made possible:

A summary of the changes, in order they are shown here:

storage.c

  • 58 header need for Windows COM stuff
  • 238 set attribute FILE_ATTR_ALIAS flag if extension is ".lnk"
  • 295 BLI_file_alias_target returns full path of a shortcut

file_draw.c

  • 224 - we will show file items that are links in a different way
  • 316 - existing code moved
  • 336 - draw little arrow at bottom-left of shortcuts
  • 357 - existing code moved

file_ops.c

  • 1472 - For multi-file selection, don't allow mixture of regular and shortcuts
  • 1626 - For shortcuts we need to setup sfile params for operators

filelist.c

  • 1018 - Also check Volumes list for icons (shortcuts to drive roots)
  • 1026 - Check shortcut target against known items too (shortcuts to desktop, etc)
  • 1043 - Offline items should get stopsign icon, not warning icon
  • 1383 - Allow previews of shortcuts by using their targets
  • 2499 - "target" var can point at root+relpath or shortcut target
  • 2511 - get shortcut target if attributes include FILE_ATTR_ALIAS
  • 2522 - Remove ".lnk" from name if valid Windows shortcut
  • 2526 - If not valid then set shortcut file to hidden
  • 2532 - Existing code moved afterward so can deal with shortcut items.

Diff Detail

Repository
rB Blender

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
source/blender/blenlib/intern/storage.c
379

From what I can see we wont use this on any other OS's - so would make this a windows spesific function. BLI_file_alias_target_win32 or so.

This revision now requires changes to proceed.Apr 15 2020, 12:50 PM

@Sergey Sharybin (sergey) - Try using early return rather than long indented block.

I wanted to avoid actually returning early as I have to clean up the memory allocated by BLI_file_read_binary_as_mem(). But I have changed that flow to make it easier to read and follow. Hopefully for the better. LOL.

@Campbell Barton (campbellbarton) - From what I can see we wont use this on any other OS's

Macs have aliases, which is a very similar file-based redirection. We have a patch around for that somewhere. Although that should just be a a few lines in total, but should work with everything I am doing here.

Should use BLI_path_extension_check.

Thanks! Done.

Still lots of experimenting to do around this. Shortcuts to folders is the most needed and also the easiest to get working. Shortcuts to ordinary files should work so will continue looking at this. But there will remain some possible shortcuts that are impossible to support. Some because they are just inapplicable, like a shortcut to Control Panel, or shortcut to Network Neighborhood. And some oddball types use some things that are not specified in the specification (the variable data inside ItemID). Some people have reverse-engineered this (https://code.google.com/archive/p/lnk-parser/), I'd rather stay with what is published in the spec.

I'm liking this new way of showing links, aliases, hard links, symlinks, etc. It means I can indicate more about the target, if needed, and it looks nicer.

Although this code is currently turning all lnk files into some link, at the end of the day I would be leaving unsupported types without a redirection path and with their ".lnk" extensions intact.

Any chance the IShellLinkW interface provide the data we need? I'd take that over reverse engineering the .lnk format

@Ray molenkamp (LazyDodo) - Any chance the IShellLinkW interface provide the data we need?

Maybe. I haven't explored that mostly because I don't know to call those things. LOL.

But if you can offer any hints, then we could always put support for this in the win32 ghost files if we need to call them from C++

I'd take that over reverse engineering the .lnk format

For sure. Although the only parts in the spec not actually specified are obscure things we generally can't support. Basically they put those known Folder Ids in there for things like "shortcut to control panel" or "shortcut to network neighborhood". But of those there are some that would come in handy if we can do so.

@Ray molenkamp (LazyDodo) - Any chance the IShellLinkW interface provide the data we need?

Maybe. I haven't explored that mostly because I don't know to call those things. LOL.
But if you can offer any hints, then we could always put support for this in the win32 ghost files if we need to call them from C++

No they are usable from C, probably easiest to start with this and kinda play with it to see if it has the info you need

#include <Windows.h>
#include <shobjidl_core.h>
#include <stdio.h>
int main()
{
    CoInitializeEx(NULL, COINIT_MULTITHREADED);
    IShellLinkW* Shortcut;
    HRESULT hr;
    hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&Shortcut);
    if (SUCCEEDED(hr))
    {
        IPersistFile* PersistFile;
        hr = Shortcut->QueryInterface(IID_IPersistFile, (LPVOID*)&PersistFile);
        if (SUCCEEDED(hr))
        {
            hr = PersistFile->Load(L"c:\\Users\\ray\\Desktop\\Dropbox.lnk", 0);
            if (SUCCEEDED(hr))
            {
                wchar_t buffer[256];
                hr = Shortcut->GetDescription(buffer, 256);
                if (SUCCEEDED(hr))
                {
                    printf("%S\n", buffer);
                }
                PersistFile->Release();
            }
        }
        Shortcut->Release();
    }
}

@Ray molenkamp (LazyDodo) - Any chance the IShellLinkW interface provide the data we need?

Actually looking at this again my memory is being refreshed a bit. That function can take up to a second to resolve links sometimes and people report that it can crash. The usual response to that is to to parse the lnk file yourself. And all examples of that pretty-much do it the same way as I am here, skipping over that ItemIDList stuff.

@Ray molenkamp (LazyDodo) wrote: - probably easiest to start with this and kinda play with it to see if it has the info you need

Awesome! Thanks. Will play with that and see how it goes.

Allright then, carry on!

@Ray molenkamp (LazyDodo) - Allright then, carry on!

Just realized that even if that IShellLinkW takes too long too resolve I could just use a hybrid approach. Quickly parse the lnk file just to determine if is a link and whether to a file or folder and set flags and display as appropriate. But then only resolve the shortcut with IShellLinkW when we actually click the thing.

While Only crashing when they click something is without a doubt better than crashing all the time, not sure it is the way to go though....

@Ray molenkamp (LazyDodo) - While Only crashing when they click something is without a doubt better than crashing all the time, not sure it is the way to go though....

I'm just hoping it will all become clearer when I start doing some testing and timing. Might be able to play a bit with it in 8 hours or so. Fun, fun, fun...

Harley Acheson (harley) edited the summary of this revision. (Show Details)Apr 17 2020, 4:08 AM

Using IShellLinkW now, seems to work quite well so far. Can now show shortcuts to folders that are also hidden and system, etc because the item attributes are taken from the link target.

Harley Acheson (harley) edited the summary of this revision. (Show Details)

Appending from shortcuts to blend files should be working. This applies to Mac too, so you should be able to append from an alias to a blend file.

Updated to current state of master. Also now have a strategy to deal with links that are invalid, point to paths we can't use, or are of a type we cannot support. Still not working with shortcuts to image files though.

Campbell Barton (campbellbarton) requested changes to this revision.Apr 29 2020, 9:26 AM

Looks OK, there are issues building on Linux (and I assume Apple too).

source/blender/blenlib/intern/storage.c
295

Should be #ifdef _WIN32.

source/blender/editors/space_file/filelist.c
2516

Not available on Linux/Apple.

This revision now requires changes to proceed.Apr 29 2020, 9:26 AM

@Ray molenkamp (LazyDodo), does this work for you? As in, can you navigate into the .lnk files?

Harley Acheson (harley) edited the summary of this revision. (Show Details)Apr 29 2020, 6:47 PM

Looks OK, there are issues building on Linux (and I assume Apple too).

Whoops, will fix that. For Apple, they have a function with the same name elsewhere that deals with their alias files, which are almost identical (file-based redirection). But yes, will make sure it compiles on Linux.

@Sergey Sharybin (sergey) - does this work for you? As in, can you navigate into the .lnk files?

Note that my own hope for the near term is to support shortcut to folders only. The rest of this experimentation is just me wondering how much could be supported eventually. Not all things are even possible, like shortcuts to Control Panel, or Network Neighborhood, etc. But knowing that at some shortcuts to files might be possible is enough to plan for marking such things visually better.

Should probably compile on Linux now. Adding some better comments about where the Apple versions are for a couple of the storage_c routines.

Crap. Despite my notes it looks like appending from a shortcut to a blend is not working, although I swear it did earlier so will figure it out. I really need to spend more time on this one....

Updated to current state of master. A bit safer, and in a shape that will (eventually) be easier to support a subset of shortcut types. Reduces the arrow used on documents, etc.

Can now APPEND from a shortcut to a blend file!!

Harley Acheson (harley) edited the summary of this revision. (Show Details)May 4 2020, 12:02 AM

Just changing how it looks when you have a shortcut/alias to a drive that is offline. So when browsing to a folder that contains such a shortcut to an empty DVD drive or empty memory stick drive.

Now shortcuts (or aliases or symlinks) to fancy decorated folders have same decorations:

Improvements to how shortcuts to folders (and to drives) are shown:

Fixing an error pointed out by @Ankit (ankitm)

Fixed a dumb error. Okay, not really. @Ray molenkamp (LazyDodo) fixed dumb error.

And also now dealing with multiple-selection without crashing. This situation is a bit interesting in that we have a single root dir and multiple file names, which doesn't work well if any in the group have full absolute paths. Now just doesn't add a shortcut/alias to the selection list in case of selecting multiples. So you can select a single alias/shortcut or multiple regular files, but not a combination. Works out okay in practice as we don't normally have piles of shortcuts to files anyway.

Harley Acheson (harley) edited the summary of this revision. (Show Details)May 7 2020, 4:00 AM
Harley Acheson (harley) edited the summary of this revision. (Show Details)May 7 2020, 4:11 AM

Cleanup, comment changes. Just small stuff.

Harley Acheson (harley) retitled this revision from UI WIP: Windows Shell Links to UI: Windows Shell Links & Improved Mac Aliases.May 7 2020, 11:05 PM
Harley Acheson (harley) edited the summary of this revision. (Show Details)
Harley Acheson (harley) edited the summary of this revision. (Show Details)May 8 2020, 3:55 AM

This now builds on Linux, although clang-format needs to be run.

This revision is now accepted and ready to land.May 8 2020, 4:54 AM

Updated to current state of master. And ran "make format" to ensure correct clang format.

This appears to work correctly for aliases on macOS.

Just updating to current state of master.

Ray molenkamp (LazyDodo) requested changes to this revision.Mon, May 11, 7:44 PM
Ray molenkamp (LazyDodo) added inline comments.
source/blender/blenlib/intern/storage.c
315
  1. Result not checked, conv_utf_8_to_16 may have failed.
  2. possible overflow if bsize > FILE_MAXDIR
323

error not checked, success assumed

source/blender/editors/space_file/file_ops.c
1627

Above we check file->redirection_path but we free file->relpath below, comment could do a better job explaining what is going to so future us won't go 'oh hey.. bug'

This revision now requires changes to proceed.Mon, May 11, 7:44 PM

Updates to incorporate changes suggested by @Ray molenkamp (LazyDodo):

  • conv_utf_8_to_16() checked for success
  • conv_utf_16_to_8() checked for success
  • Overwriting file->relpath given much better explanation
Harley Acheson (harley) marked an inline comment as done.

Fixing an issue pointed out by @Ray molenkamp (LazyDodo). There was an unneeded call to count_utf_16_from_8() that was used (incorrectly) as an argument to conv_utf_8_to_16(). This had the potential of not handling an error if the passed filepath converted to a UTC16 that overflowed my buffer.

Just updating to reflect recent changes to master.

This revision is now accepted and ready to land.Fri, May 15, 5:45 PM
Julian Eisel (Severin) accepted this revision.EditedMon, May 18, 12:40 AM

Didn't dig too deep, but everything seems reasonable. I noted some points, they are just cosmetic though.
@Bastien Montagne (mont29) should get a chance to intervene here, he's module owner -- Feel free to remove yourself as reviewer if you think it's gotten enough treatment already :)

The icons look quite small compared to the screenshots above. Not sure if that is the intended size or if that's a hiDPI issue. Default DPI on Retina:

For these hidden items the icon is also barely visible, although I don't think that's a big deal.
I did prefer the previous arrow icon though. The more round one feels much closer to the standard icon used in Windows, macOS and Linux for me.

source/blender/editors/space_file/filelist.c
1044

The cancel icon looks like you can click the item to remove it. Would prefer to keep ICON_ERROR.

Some changes based on recommendations from @Julian Eisel (Severin):

Arrow used for shortcuts/aliases/links changed to the "old" arrow:

And they should scale better on high-dpi screens.

Also going back to using ICON_ERROR (warning) for drives that are offline, rather than ICON_CANCEL (stopsign).

Just updating to current state of master. No changes.

Did very quick skim-review and saw nothing wrong here, feature is nice to have, so LGTM.