[haiku-commits] haiku: hrev45848 - in src: kits/tracker add-ons/input_server/filters/shortcut_catcher add-ons/tracker

  • From: stpere@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 11 Jul 2013 18:49:31 +0200 (CEST)

hrev45848 adds 4 changesets to branch 'master'
old head: 02b151d3e344772bcc6f91c874b9b87a23350a0a
new head: d058a4aed272a9fe79ef9e8443fad3bb5352e433
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=d058a4a+%5E02b151d

----------------------------------------------------------------------------

56ea7a1: Rename Tracker add-ons to remove shortcut suffix

1412a36: Shortcut add-on: change to accomodate tracker add-ons
  
  * Ignore shortcuts regardings tracker add-ons. Its settings file is now shared
  with Tracker, and those are now handled by Tracker.
  * Use a BPathMonitor as specified in a TODO to check the presence and changes 
on
  the settings file. (#6278)
  * Use a message to ask Tracker to launch/open folders as specified in TODO

41e6527: Tracker addons: strip shortcut from name, instead use resource

d058a4a: Tracker: store default add-ons shortcuts in resource
  
  * Default shortcuts for add-ons are now stored within the binary as a resource
  (it was previously appended to the file name, as Open Terminal-T, for example)
  * Use ~/config/shortcuts_settings to override those default shortcuts
  (editable with Shortcuts preflet)
  * Tracker avoid rescanning the add-ons directories when unnecessary
  * Monitor the shortcuts_settings to apply changes on the fly
  * Fallback to default shortcuts whenever appropriate (settings file deleted, 
etc.)
  * Should fix #4446 (with resource rather than attributes)

                                [ Philippe Saint-Pierre <stpere@xxxxxxxxx> ]

----------------------------------------------------------------------------

23 files changed, 404 insertions(+), 251 deletions(-)
build/jam/HaikuImage                             |  10 +-
.../filters/shortcut_catcher/Jamfile             |   2 +
.../filters/shortcut_catcher/KeyCommandMap.cpp   |  66 +++-
.../filters/shortcut_catcher/KeyCommandMap.h     |   2 +
.../shortcut_catcher/ParseCommandLine.cpp        |  28 +-
src/add-ons/tracker/filetype/FileType.rdef       |   1 +
src/add-ons/tracker/filetype/Jamfile             |   4 +-
src/add-ons/tracker/mark_as/Jamfile              |   4 +-
src/add-ons/tracker/mark_as/MarkAsRead.rdef      |   1 +
src/add-ons/tracker/opentargetfolder/Jamfile     |   2 +-
.../opentargetfolder/opentargetfolder.rdef       |   2 +
src/add-ons/tracker/openterminal/Jamfile         |   4 +-
.../tracker/openterminal/OpenTerminal.rdef       |   1 +
src/add-ons/tracker/zipomatic/Jamfile            |   4 +-
src/add-ons/tracker/zipomatic/ZipOMatic.rdef     |   1 +
src/apps/diskusage/DiskUsage.rdef                |   2 +
src/apps/text_search/TextSearch.rdef             |   1 +
src/kits/tracker/ContainerWindow.cpp             | 188 +++---------
src/kits/tracker/ContainerWindow.h               |  12 +-
src/kits/tracker/DeskWindow.cpp                  | 299 +++++++++++++++----
src/kits/tracker/DeskWindow.h                    |  14 +-
src/kits/tracker/Jamfile                         |   5 +-
src/preferences/backgrounds/Backgrounds.rdef     |   2 +

############################################################################

Commit:      56ea7a1e1908ba161a5d9dc3a5f0e578e3a7439d
URL:         http://cgit.haiku-os.org/haiku/commit/?id=56ea7a1
Author:      Philippe Saint-Pierre <stpere@xxxxxxxxx>
Date:        Thu Jul 11 16:04:23 2013 UTC

Rename Tracker add-ons to remove shortcut suffix

----------------------------------------------------------------------------

diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage
index 37f3459..640e9cf 100644
--- a/build/jam/HaikuImage
+++ b/build/jam/HaikuImage
@@ -648,14 +648,14 @@ AddFilesToHaikuImage system add-ons media : 
$(SYSTEM_ADD_ONS_MEDIA) ;
 AddFilesToHaikuImage system add-ons media plugins
        : $(SYSTEM_ADD_ONS_MEDIA_PLUGINS) ;
 AddFilesToHaikuImage system add-ons Tracker
-       : FileType-F Mark\ as… Mark\ as\ Read-R Open\ Target\ Folder-O
-       Open\ Terminal-T ZipOMatic-Z ;
+       : FileType Mark\ as… Mark\ as\ Read Open\ Target\ Folder
+       Open\ Terminal ZipOMatic ;
 AddSymlinkToHaikuImage system add-ons Tracker
-       : /boot/system/preferences/Backgrounds : Background-B ;
+       : /boot/system/preferences/Backgrounds : Background ;
 AddSymlinkToHaikuImage system add-ons Tracker
-       : /boot/system/apps/TextSearch : TextSearch-G ;
+       : /boot/system/apps/TextSearch : TextSearch ;
 AddSymlinkToHaikuImage system add-ons Tracker
-       : /boot/system/apps/DiskUsage : DiskUsage-I ;
+       : /boot/system/apps/DiskUsage : DiskUsage ;
 AddFilesToHaikuImage system add-ons input_server devices
        : <input>keyboard <input>mouse <input>tablet <input>wacom ;
 AddFilesToHaikuImage system add-ons input_server filters

############################################################################

Commit:      1412a36abcf4b4e7a7e652a19c4a70b3c2227c06
URL:         http://cgit.haiku-os.org/haiku/commit/?id=1412a36
Author:      Philippe Saint-Pierre <stpere@xxxxxxxxx>
Date:        Thu Jul 11 16:07:03 2013 UTC

Ticket:      https://dev.haiku-os.org/ticket/6278

Shortcut add-on: change to accomodate tracker add-ons

* Ignore shortcuts regardings tracker add-ons. Its settings file is now shared
with Tracker, and those are now handled by Tracker.
* Use a BPathMonitor as specified in a TODO to check the presence and changes on
the settings file. (#6278)
* Use a message to ask Tracker to launch/open folders as specified in TODO

----------------------------------------------------------------------------

diff --git a/src/add-ons/input_server/filters/shortcut_catcher/Jamfile 
b/src/add-ons/input_server/filters/shortcut_catcher/Jamfile
index 0182b9f..f80ca1d 100644
--- a/src/add-ons/input_server/filters/shortcut_catcher/Jamfile
+++ b/src/add-ons/input_server/filters/shortcut_catcher/Jamfile
@@ -2,6 +2,8 @@ SubDir HAIKU_TOP src add-ons input_server filters 
shortcut_catcher ;
 
 SetSubDirSupportedPlatformsBeOSCompatible ;
 
+UsePrivateHeaders storage ;
+
 #      Common files used here and in the app
 StaticLibrary libshortcuts_shared.a :
        BitFieldTesters.cpp
diff --git 
a/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.cpp 
b/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.cpp
index 40e6cae..9d2ad01 100644
--- a/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.cpp
+++ b/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.cpp
@@ -14,9 +14,12 @@
 #include <Beep.h>
 #include <Entry.h>
 #include <File.h>
+#include <FindDirectory.h>
 #include <MessageFilter.h>
 #include <NodeMonitor.h>
 #include <OS.h>
+#include <Path.h>
+#include <PathMonitor.h>
 #include <WindowScreen.h>
 
 #include "BitFieldTesters.h"
@@ -71,20 +74,19 @@ KeyCommandMap::KeyCommandMap(const char* file)
        strcpy(fFileName, file);
 
        BEntry fileEntry(fFileName);
-       // TODO: Using a BPathMonitor would be preferable. See discussion 
linked off
-       // ticket #6278.
-       if (!fileEntry.Exists())
-               BFile file(fFileName, B_READ_ONLY | B_CREATE_FILE);
-       
-       if (fileEntry.InitCheck() == B_NO_ERROR) {
-               node_ref nref;
 
-               if (fileEntry.GetNodeRef(&nref) == B_NO_ERROR)
-                       watch_node(&nref, B_WATCH_STAT, this);
+       BEntry parent;
+       BPath parentPath;
+       if (fileEntry.GetParent(&parent) == B_OK
+               && parent.GetPath(&parentPath) == B_OK) {
+               BPrivate::BPathMonitor::StartWatching(parentPath.Path(),
+                       B_WATCH_STAT | B_WATCH_FILES_ONLY, this);
        }
 
-       BMessage msg(FILE_UPDATED);
-       PostMessage(&msg);
+       if (fileEntry.InitCheck() == B_NO_ERROR) {
+               BMessage msg(FILE_UPDATED);
+               PostMessage(&msg);
+       }
 
        fPort = create_port(1, SHORTCUTS_CATCHER_PORT_NAME);
        _PutMessageToPort();
@@ -100,7 +102,7 @@ KeyCommandMap::~KeyCommandMap()
        for (int i = fInjects.CountItems() - 1; i >= 0; i--)
                delete (BMessage*)fInjects.ItemAt(i);
 
-       stop_watching(this);
+       BPrivate::BPathMonitor::StopWatching(BMessenger(this, this));
                // don't know if this is necessary, but it can't hurt
        _DeleteHKSList(fSpecs);
        delete [] fFileName;
@@ -219,7 +221,21 @@ KeyCommandMap::MessageReceived(BMessage* msg)
                        _PutMessageToPort();
                        break;
 
-               case B_NODE_MONITOR:
+               case B_PATH_MONITOR:
+               {
+                       const char* path = "";
+                       // only fall through for appropriate file
+                       if (!(msg->FindString("path", &path) == B_OK
+                                       && strcmp(path, fFileName) == 0)) {
+                               dev_t device;
+                               ino_t node;
+                               if (msg->FindInt32("device", &device) != B_OK
+                                       && msg->FindInt64("node", &node) != B_OK
+                                       && device != fNodeRef.device
+                                       && node != fNodeRef.node)
+                                       break;
+                       }
+               }
                case FILE_UPDATED:
                {
                        BMessage fileMsg;
@@ -231,6 +247,7 @@ KeyCommandMap::MessageReceived(BMessage* msg)
                                // defaults to no deletion
                                BList* oldList = NULL;
 
+                               file.GetNodeRef(&fNodeRef);
                                int i = 0;
                                BMessage msg;
                                while (fileMsg.FindMessage("spec", i++, &msg) 
== B_OK) {
@@ -241,6 +258,27 @@ KeyCommandMap::MessageReceived(BMessage* msg)
                                        if (msg.FindInt32("key", (int32*) &key) 
== B_OK
                                                && msg.FindMessage("act", 
&actMsg) == B_OK
                                                && msg.FindMessage("modtester", 
&testerMsg) == B_OK) {
+                                               
+                                               // Leave handling of add-ons 
shortcuts to Tracker
+                                               BString command;
+                                               if (actMsg.FindString("largv", 
&command) == B_OK) {
+                                                       BPath path;
+                                                       if 
(find_directory(B_SYSTEM_ADDONS_DIRECTORY, &path) == B_OK) {
+                                                               
path.Append("Tracker/");
+                                                               if 
(command.FindFirst(path.Path()) != B_ERROR)
+                                                                       
continue;
+                                                       }
+                                                       if 
(find_directory(B_COMMON_ADDONS_DIRECTORY, &path) == B_OK) {
+                                                               
path.Append("Tracker/");
+                                                               if 
(command.FindFirst(path.Path()) != B_ERROR)
+                                                                       
continue;
+                                                       }
+                                                       if 
(find_directory(B_USER_ADDONS_DIRECTORY, &path) == B_OK) {
+                                                               
path.Append("Tracker/");
+                                                               if 
(command.FindFirst(path.Path()) != B_ERROR)
+                                                                       
continue;
+                                                       }
+                                               }
                                                BArchivable* archive = 
instantiate_object(&testerMsg);
                                                if (BitFieldTester* tester
                                                                = 
dynamic_cast<BitFieldTester*>(archive)) {
@@ -282,7 +320,7 @@ KeyCommandMap::_DeleteHKSList(BList* l)
        if (l != NULL) {
                int num = l->CountItems();
                for (int i = 0; i < num; i++)
-                       delete ((hks*) l->ItemAt(i));
+                       delete ((hks*) l->ItemAt(0));
                delete l;
        }
 }
diff --git a/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.h 
b/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.h
index b70e7c6..9ade3d0 100644
--- a/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.h
+++ b/src/add-ons/input_server/filters/shortcut_catcher/KeyCommandMap.h
@@ -18,6 +18,7 @@
 #include <Messenger.h>
 #include <Message.h>
 #include <MessageFilter.h>
+#include <Node.h>
 
 // Maps BMessages to ShortcutsSpecs!
 // The thread here gets file update messages, and updates
@@ -49,6 +50,7 @@ private:
                                
                                port_id                         fPort;
                                char*                           fFileName;
+                               node_ref                        fNodeRef;
                                BLocker                         fSyncSpecs;     
// locks the lists below
                                BList                           fInjects;
                                BList*                          fSpecs; 
diff --git 
a/src/add-ons/input_server/filters/shortcut_catcher/ParseCommandLine.cpp 
b/src/add-ons/input_server/filters/shortcut_catcher/ParseCommandLine.cpp
index b7dbde0..c9dfc8c 100644
--- a/src/add-ons/input_server/filters/shortcut_catcher/ParseCommandLine.cpp
+++ b/src/add-ons/input_server/filters/shortcut_catcher/ParseCommandLine.cpp
@@ -26,9 +26,10 @@
 #include <SupportKit.h>
 
 
+const char *kTrackerSignature = "application/x-vnd.Be-TRAK";
+
 // This char is used to hold words together into single words...
 #define GUNK_CHAR 0x01
-#define PATHTOTRACKER "/system/Tracker"
 
 // Turn all spaces that are not-to-be-counted-as-spaces into GUNK_CHAR chars.
 static void
@@ -219,7 +220,6 @@ CloneArgv(char** argv)
 }
 
 
-
 BString
 ParseArgvZeroFromString(const char* command)
 {
@@ -299,24 +299,22 @@ LaunchCommand(char** argv, int32 argc)
                // than launch.
                BDirectory testDir(&entry);
                if (testDir.InitCheck() == B_NO_ERROR) {
-                       // Hack way to do this--really I should be able to do 
this by 
-                       // sending a BMessage. But how? When I finally get my 
copy of the
-                       // BeOS Bible, maybe then I'll find out.
-                       BPath trackerPath;
-                       if (find_directory(B_SYSTEM_DIRECTORY, &trackerPath) != 
B_OK
-                               || trackerPath.Append("Tracker") != B_OK) {
-                               return B_ENTRY_NOT_FOUND;
-                       }
-                       BString cmd(trackerPath.Path());
-                       cmd << " '" << argv[0] << "'";
-                       system(cmd.String());
-                       return B_NO_ERROR;
+                       entry_ref ref;
+                       status_t status = entry.GetRef(&ref);
+                       if (status < B_OK)
+                               return status;
+
+                       BMessenger target(kTrackerSignature);
+                       BMessage message(B_REFS_RECEIVED);
+                       message.AddRef("refs", &ref);
+
+                       return target.SendMessage(&message);
                } else {
                        // It's not a directory. Must be a file.
                        entry_ref ref;
                        if (entry.GetRef(&ref) == B_NO_ERROR) {
                                if (argc > 1) 
-                                       be_roster->Launch(&ref, argc-1, 
&argv[1]);
+                                       be_roster->Launch(&ref, argc - 1, 
&argv[1]);
                                else
                                        be_roster->Launch(&ref);
                                return B_NO_ERROR;

############################################################################

Commit:      41e6527c1f3ad44721041c02bb19eecc0a1198bd
URL:         http://cgit.haiku-os.org/haiku/commit/?id=41e6527
Author:      Philippe Saint-Pierre <stpere@xxxxxxxxx>
Date:        Thu Jul 11 16:30:10 2013 UTC

Tracker addons: strip shortcut from name, instead use resource

----------------------------------------------------------------------------

diff --git a/src/add-ons/tracker/filetype/FileType.rdef 
b/src/add-ons/tracker/filetype/FileType.rdef
index f51396c..329d140 100644
--- a/src/add-ons/tracker/filetype/FileType.rdef
+++ b/src/add-ons/tracker/filetype/FileType.rdef
@@ -110,3 +110,4 @@ resource mini_icon array {
 
 #endif // HAIKU_TARGET_PLATFORM_HAIKU
 
+resource(100, "default_shortcut") "F";
diff --git a/src/add-ons/tracker/filetype/Jamfile 
b/src/add-ons/tracker/filetype/Jamfile
index 8ca0227..f2209a6 100644
--- a/src/add-ons/tracker/filetype/Jamfile
+++ b/src/add-ons/tracker/filetype/Jamfile
@@ -3,9 +3,9 @@ SubDir HAIKU_TOP src add-ons tracker filetype ;
 SetSubDirSupportedPlatformsBeOSCompatible ;
 
 # TODO: does not seem to work:
-AddResources FileType-F : FileType.rdef ;
+AddResources FileType : FileType.rdef ;
 
-Addon FileType-F :
+Addon FileType :
        FileType.cpp
 
        : be tracker
diff --git a/src/add-ons/tracker/mark_as/Jamfile 
b/src/add-ons/tracker/mark_as/Jamfile
index 0a22ea1..f8492aa 100644
--- a/src/add-ons/tracker/mark_as/Jamfile
+++ b/src/add-ons/tracker/mark_as/Jamfile
@@ -5,14 +5,14 @@ SetSubDirSupportedPlatformsBeOSCompatible ;
 UsePrivateHeaders mail ;
 
 AddResources Mark\ as… : MarkAs.rdef ;
-AddResources Mark\ as\ Read-R : MarkAsRead.rdef ;
+AddResources Mark\ as\ Read : MarkAsRead.rdef ;
 
 Addon Mark\ as… :
        MarkAs.cpp
        : be tracker $(TARGET_LIBSUPC++) libmail.so
 ;
 
-Addon Mark\ as\ Read-R :
+Addon Mark\ as\ Read :
        MarkAsRead.cpp
        : be tracker $(TARGET_LIBSUPC++) libmail.so
 ;
diff --git a/src/add-ons/tracker/mark_as/MarkAsRead.rdef 
b/src/add-ons/tracker/mark_as/MarkAsRead.rdef
index 8ebf49e..ec62047 100644
--- a/src/add-ons/tracker/mark_as/MarkAsRead.rdef
+++ b/src/add-ons/tracker/mark_as/MarkAsRead.rdef
@@ -32,3 +32,4 @@ resource vector_icon {
        $"000A020105000A03010200"
 };
 
+resource(100, "default_shortcut") "R";
diff --git a/src/add-ons/tracker/opentargetfolder/Jamfile 
b/src/add-ons/tracker/opentargetfolder/Jamfile
index c44dfd8..0fcc931 100644
--- a/src/add-ons/tracker/opentargetfolder/Jamfile
+++ b/src/add-ons/tracker/opentargetfolder/Jamfile
@@ -1,6 +1,6 @@
 SubDir HAIKU_TOP src add-ons tracker opentargetfolder ;
 
-Application Open\ Target\ Folder-O : 
+Application Open\ Target\ Folder : 
        opentargetfolder.cpp
 
        : be tracker $(TARGET_LIBSUPC++)
diff --git a/src/add-ons/tracker/opentargetfolder/opentargetfolder.rdef 
b/src/add-ons/tracker/opentargetfolder/opentargetfolder.rdef
index c9afdf1..8d525a5 100644
--- a/src/add-ons/tracker/opentargetfolder/opentargetfolder.rdef
+++ b/src/add-ons/tracker/opentargetfolder/opentargetfolder.rdef
@@ -92,3 +92,5 @@ resource mini_icon array {
 };
 
 #endif // HAIKU_TARGET_PLATFORM_HAIKU
+
+resource(100, "default_shortcut") "O";
diff --git a/src/add-ons/tracker/openterminal/Jamfile 
b/src/add-ons/tracker/openterminal/Jamfile
index 63f6c26..93a8d35 100644
--- a/src/add-ons/tracker/openterminal/Jamfile
+++ b/src/add-ons/tracker/openterminal/Jamfile
@@ -2,9 +2,9 @@ SubDir HAIKU_TOP src add-ons tracker openterminal ;
 
 SetSubDirSupportedPlatformsBeOSCompatible ;
 
-AddResources Open\ Terminal-T : OpenTerminal.rdef ;
+AddResources Open\ Terminal : OpenTerminal.rdef ;
 
-Addon Open\ Terminal-T :
+Addon Open\ Terminal :
        OpenTerminal.cpp
 
        : be tracker $(TARGET_LIBSTDC++)
diff --git a/src/add-ons/tracker/openterminal/OpenTerminal.rdef 
b/src/add-ons/tracker/openterminal/OpenTerminal.rdef
index e413574..fae9ae6 100644
--- a/src/add-ons/tracker/openterminal/OpenTerminal.rdef
+++ b/src/add-ons/tracker/openterminal/OpenTerminal.rdef
@@ -42,3 +42,4 @@ resource vector_icon {
        $"B30CB30C0A0C0110000A0B010F2032290A09010D2032BA450A09010D2036BB11"
 };
 
+resource("default_shortcut") "T";
diff --git a/src/add-ons/tracker/zipomatic/Jamfile 
b/src/add-ons/tracker/zipomatic/Jamfile
index f974e05..4c84ea6 100644
--- a/src/add-ons/tracker/zipomatic/Jamfile
+++ b/src/add-ons/tracker/zipomatic/Jamfile
@@ -2,7 +2,7 @@ SubDir HAIKU_TOP src add-ons tracker zipomatic ;
 
 UsePrivateHeaders shared ;
 
-Application ZipOMatic-Z :
+Application ZipOMatic :
        GenericThread.cpp
        ZipOMatic.cpp
        ZipOMaticActivity.cpp
@@ -13,7 +13,7 @@ Application ZipOMatic-Z :
        : ZipOMatic.rdef
 ;
 
-DoCatalogs ZipOMatic-Z :
+DoCatalogs ZipOMatic :
        x-vnd.haiku.zip-o-matic
        :
        ZipOMatic.cpp
diff --git a/src/add-ons/tracker/zipomatic/ZipOMatic.rdef 
b/src/add-ons/tracker/zipomatic/ZipOMatic.rdef
index 052f62e..d817c0e 100644
--- a/src/add-ons/tracker/zipomatic/ZipOMatic.rdef
+++ b/src/add-ons/tracker/zipomatic/ZipOMatic.rdef
@@ -59,3 +59,4 @@ resource vector_icon {
        $"0111000A0B010E000A0C010F000A0B011000"
 };
 
+resource(100, "default_shortcut") "Z";
diff --git a/src/apps/diskusage/DiskUsage.rdef 
b/src/apps/diskusage/DiskUsage.rdef
index 0205feb..7e5158c 100644
--- a/src/apps/diskusage/DiskUsage.rdef
+++ b/src/apps/diskusage/DiskUsage.rdef
@@ -49,3 +49,5 @@ resource vector_icon {
        $"18001501178600040A01010B1815FF01178400040A08010C000A09010D000A0A"
        $"010E00"
 };
+
+resource(100, "default_shortcut") "I";
diff --git a/src/apps/text_search/TextSearch.rdef 
b/src/apps/text_search/TextSearch.rdef
index 3bad6e5..7beffcd 100644
--- a/src/apps/text_search/TextSearch.rdef
+++ b/src/apps/text_search/TextSearch.rdef
@@ -45,3 +45,4 @@ resource vector_icon {
        $"000A09010C023C00000000000000003C000048B00048F000"
 };
 
+resource(100, "default_shortcut") "G";
diff --git a/src/preferences/backgrounds/Backgrounds.rdef 
b/src/preferences/backgrounds/Backgrounds.rdef
index 668c823..2099c29 100644
--- a/src/preferences/backgrounds/Backgrounds.rdef
+++ b/src/preferences/backgrounds/Backgrounds.rdef
@@ -58,3 +58,5 @@ resource vector_icon {
        $"000A0D0114000A00011500"
 };
 
+resource(100, "default_shortcut") "B";
+

############################################################################

Revision:    hrev45848
Commit:      d058a4aed272a9fe79ef9e8443fad3bb5352e433
URL:         http://cgit.haiku-os.org/haiku/commit/?id=d058a4a
Author:      Philippe Saint-Pierre <stpere@xxxxxxxxx>
Date:        Thu Jul 11 16:32:19 2013 UTC

Ticket:      https://dev.haiku-os.org/ticket/4446

Tracker: store default add-ons shortcuts in resource

* Default shortcuts for add-ons are now stored within the binary as a resource
(it was previously appended to the file name, as Open Terminal-T, for example)
* Use ~/config/shortcuts_settings to override those default shortcuts
(editable with Shortcuts preflet)
* Tracker avoid rescanning the add-ons directories when unnecessary
* Monitor the shortcuts_settings to apply changes on the fly
* Fallback to default shortcuts whenever appropriate (settings file deleted, 
etc.)
* Should fix #4446 (with resource rather than attributes)

----------------------------------------------------------------------------

diff --git a/src/kits/tracker/ContainerWindow.cpp 
b/src/kits/tracker/ContainerWindow.cpp
index c2380b2..3721538 100644
--- a/src/kits/tracker/ContainerWindow.cpp
+++ b/src/kits/tracker/ContainerWindow.cpp
@@ -145,6 +145,8 @@ const int32 kWindowStaggerBy = 17;
 
 BRect BContainerWindow::sNewWindRect(85, 50, 548, 280);
 
+LockingList<AddonShortcut>* BContainerWindow::fAddonsList
+       = new LockingList<struct AddonShortcut>(10, true);
 
 namespace BPrivate {
 
@@ -165,48 +167,6 @@ ActivateWindowFilter(BMessage*, BHandler** target, 
BMessageFilter*)
 }
 
 
-static void
-StripShortcut(const Model* model, char* result, uint32 &shortcut)
-{
-       // model name (possibly localized) for the menu item label
-       strlcpy(result, model->Name(), B_FILE_NAME_LENGTH);
-
-       // check if there is a shortcut in the model name
-       uint32 length = strlen(result);
-       if (length > 2 && result[length - 2] == '-') {
-               shortcut = result[length - 1];
-               result[length - 2] = '\0';
-               return;
-       }
-
-       // check if there is a shortcut in the filename
-       char* refName = model->EntryRef()->name;
-       length = strlen(refName);
-       if (length > 2 && refName[length - 2] == '-') {
-               shortcut = refName[length - 1];
-               return;
-       }
-
-       shortcut = '\0';
-}
-
-
-static const Model*
-MatchOne(const Model* model, void* castToName)
-{
-       char buffer[B_FILE_NAME_LENGTH];
-       uint32 dummy;
-       StripShortcut(model, buffer, dummy);
-
-       if (strcmp(buffer, (const char*)castToName) == 0) {
-               // found match, bail out
-               return model;
-       }
-
-       return 0;
-}
-
-
 int
 CompareLabels(const BMenuItem* item1, const BMenuItem* item2)
 {
@@ -217,8 +177,8 @@ CompareLabels(const BMenuItem* item1, const BMenuItem* 
item2)
 
 
 static bool
-AddOneAddon(const Model* model, const char* name, uint32 shortcut,
-       bool primary, void* context)
+AddOneAddon(const Model* model, const char* name, uint32 shortcut, 
+       uint32 modifiers, bool primary, void* context)
 {
        AddOneAddonParams* params = (AddOneAddonParams*)context;
 
@@ -226,7 +186,7 @@ AddOneAddon(const Model* model, const char* name, uint32 
shortcut,
        message->AddRef("refs", model->EntryRef());
 
        ModelMenuItem* item = new ModelMenuItem(model, name, message,
-               (char)shortcut, B_OPTION_KEY);
+               (char)shortcut, modifiers);
 
        if (primary)
                params->primaryList->AddItem(item);
@@ -2919,114 +2879,56 @@ BContainerWindow::AddTrashContextMenus(BMenu* menu)
 
 void
 BContainerWindow::EachAddon(bool (*eachAddon)(const Model*, const char*,
-       uint32 shortcut, bool primary, void* context), void* passThru,
-       BObjectList<BString> &mimeTypes)
-{
-       BObjectList<Model> uniqueList(10, true);
-       BPath path;
-       bool bail = false;
-       if (find_directory(B_BEOS_ADDONS_DIRECTORY, &path) == B_OK)
-               bail = EachAddon(path, eachAddon, &uniqueList, passThru, 
mimeTypes);
-
-       if (!bail && find_directory(B_USER_ADDONS_DIRECTORY, &path) == B_OK)
-               bail = EachAddon(path, eachAddon, &uniqueList, passThru, 
mimeTypes);
-
-       if (!bail && find_directory(B_COMMON_ADDONS_DIRECTORY, &path) == B_OK)
-               EachAddon(path, eachAddon, &uniqueList, passThru, mimeTypes);
-}
-
-
-bool
-BContainerWindow::EachAddon(BPath &path, bool (*eachAddon)(const Model*,
-       const char*, uint32 shortcut, bool primary, void*),
-       BObjectList<Model>* uniqueList, void* params,
-       BObjectList<BString> &mimeTypes)
+       uint32 shortcut, uint32 modifiers, bool primary, void* context), 
+       void* passThru, BObjectList<BString> &mimeTypes)
 {
-       path.Append("Tracker");
-
-       BDirectory dir;
-       BEntry entry;
-
-       if (dir.SetTo(path.Path()) != B_OK)
-               return false;
-
-       dir.Rewind();
-       while (dir.GetNextEntry(&entry) == B_OK) {
-               Model* model = new Model(&entry);
-
-               if (model->InitCheck() == B_OK && model->IsSymLink()) {
-                       // resolve symlinks
-                       Model* resolved = new Model(model->EntryRef(), true, 
true);
-                       if (resolved->InitCheck() == B_OK)
-                               model->SetLinkTo(resolved);
-                       else
-                               delete resolved;
-               }
-               if (model->InitCheck() != B_OK
-                       || !model->ResolveIfLink()->IsExecutable()) {
-                       delete model;
-                       continue;
-               }
-
-               // check if it supports at least one of the selected entries
-
-               bool primary = false;
-
-               if (mimeTypes.CountItems()) {
-                       BFile file(&entry, B_READ_ONLY);
-                       if (file.InitCheck() == B_OK) {
-                               BAppFileInfo info(&file);
-                               if (info.InitCheck() == B_OK) {
-                                       bool secondary = true;
-
-                                       // does this add-on has types set at 
all?
-                                       BMessage message;
-                                       if (info.GetSupportedTypes(&message) == 
B_OK) {
-                                               type_code type;
-                                               int32 count;
-                                               if (message.GetInfo("types", 
&type, &count) == B_OK)
-                                                       secondary = false;
-                                       }
+       AutoLock<LockingList<AddonShortcut> > lock(fAddonsList);
+       if (lock.IsLocked()) {
+               for (int i = fAddonsList->CountItems() - 1; i >= 0; i--) {
+                       struct AddonShortcut* item = fAddonsList->ItemAt(i);
+                       bool primary = false;
+
+                       if (mimeTypes.CountItems()) {
+                               BFile file(item->model->EntryRef(), 
B_READ_ONLY);
+                               if (file.InitCheck() == B_OK) {
+                                       BAppFileInfo info(&file);
+                                       if (info.InitCheck() == B_OK) {
+                                               bool secondary = true;
+
+                                               // does this add-on has types 
set at all?
+                                               BMessage message;
+                                               if 
(info.GetSupportedTypes(&message) == B_OK) {
+                                                       type_code type;
+                                                       int32 count;
+                                                       if 
(message.GetInfo("types", &type,
+                                                                       &count) 
== B_OK)
+                                                               secondary = 
false;
+                                               }
 
-                                       // check all supported types if it has 
some set
-                                       if (!secondary) {
-                                               for (int32 i = 
mimeTypes.CountItems();
-                                                               !primary && i-- 
> 0;) {
-                                                       BString* type = 
mimeTypes.ItemAt(i);
-                                                       if 
(info.IsSupportedType(type->String())) {
-                                                               BMimeType 
mimeType(type->String());
-                                                               if 
(info.Supports(&mimeType))
-                                                                       primary 
= true;
-                                                               else
-                                                                       
secondary = true;
+                                               // check all supported types if 
it has some set
+                                               if (!secondary) {
+                                                       for (int32 i = 
mimeTypes.CountItems();
+                                                                       
!primary && i-- > 0;) {
+                                                               BString* type = 
mimeTypes.ItemAt(i);
+                                                               if 
(info.IsSupportedType(type->String())) {
+                                                                       
BMimeType mimeType(type->String());
+                                                                       if 
(info.Supports(&mimeType))
+                                                                               
primary = true;
+                                                                       else
+                                                                               
secondary = true;
+                                                               }
                                                        }
                                                }
-                                       }
 
-                                       if (!secondary && !primary) {
-                                               delete model;
-                                               continue;
+                                               if (!secondary && !primary)
+                                                       continue;
                                        }
                                }
                        }
+                       ((eachAddon)(item->model, item->model->Name(), 
item->key,
+                               item->modifiers, primary, passThru));
                }
-
-               char name[B_FILE_NAME_LENGTH];
-               uint32 key;
-               StripShortcut(model, name, key);
-
-               // do a uniqueness check
-               if (uniqueList->EachElement(MatchOne, name)) {
-                       // found one already in the list
-                       delete model;
-                       continue;
-               }
-               uniqueList->AddItem(model);
-
-               if ((eachAddon)(model, name, key, primary, params))
-                       return true;
        }
-       return false;
 }
 
 
diff --git a/src/kits/tracker/ContainerWindow.h 
b/src/kits/tracker/ContainerWindow.h
index 138d4f6..6935c24 100644
--- a/src/kits/tracker/ContainerWindow.h
+++ b/src/kits/tracker/ContainerWindow.h
@@ -72,6 +72,13 @@ enum {
        kRestoreDecor           = 0x4
 };
 
+struct AddonShortcut {
+       Model*  model;
+       char    key;
+       char    defaultKey;
+       uint32  modifiers;
+};
+
 class BContainerWindow : public BWindow {
        public:
                BContainerWindow(LockingList<BWindow>* windowList,
@@ -173,7 +180,8 @@ class BContainerWindow : public BWindow {
 
                // add-on iteration
                void EachAddon(bool (*)(const Model*, const char*, uint32 
shortcut,
-                       bool primary, void*), void*, BObjectList<BString> &);
+                       uint32 modifiers, bool primary, void*), void*,
+                       BObjectList<BString> &);
 
                BPopUpMenu* ContextMenu();
 
@@ -291,6 +299,8 @@ class BContainerWindow : public BWindow {
                uint32 fContainerWindowFlags;
                BackgroundImage* fBackgroundImage;
 
+               static LockingList<struct AddonShortcut>* fAddonsList;
+
        private:
                BRect fSavedZoomRect;
                BRect fPreviousBounds;
diff --git a/src/kits/tracker/DeskWindow.cpp b/src/kits/tracker/DeskWindow.cpp
index b8ea334..1584f9b 100644
--- a/src/kits/tracker/DeskWindow.cpp
+++ b/src/kits/tracker/DeskWindow.cpp
@@ -38,7 +38,9 @@ All rights reserved.
 #include <Locale.h>
 #include <NodeMonitor.h>
 #include <Path.h>
+#include <PathMonitor.h>
 #include <PopUpMenu.h>
+#include <Resources.h>
 #include <Roster.h>
 #include <Screen.h>
 #include <Volume.h>
@@ -55,6 +57,7 @@ All rights reserved.
 #include "DeskWindow.h"
 #include "FSUtils.h"
 #include "IconMenuItem.h"
+#include "KeyInfos.h"
 #include "MountMenu.h"
 #include "PoseView.h"
 #include "Tracker.h"
@@ -64,44 +67,117 @@ All rights reserved.
 const char* kShelfPath = "tracker_shelf";
        // replicant support
 
+const char* kShortcutsSettings = "shortcuts_settings";
+const char* kDefaultShortcut = "default_shortcut";
+const uint32 kDefaultModifiers = B_OPTION_KEY | B_COMMAND_KEY;
 
-static void
-WatchAddOnDir(directory_which dirName, BDeskWindow* window)
+static struct AddonShortcut*
+MatchOne(struct AddonShortcut* item, void* castToName)
 {
-       BPath path;
-       if (find_directory(dirName, &path) == B_OK) {
-               path.Append("Tracker");
-               BNode node(path.Path());
-               node_ref nodeRef;
-               node.GetNodeRef(&nodeRef);
-               TTracker::WatchNode(&nodeRef, B_WATCH_DIRECTORY, window);
+       if (strcmp(item->model->Name(), (const char*)castToName) == 0) {
+               // found match, bail out
+               return item;
        }
-}
 
+       return 0;
+}
 
-struct AddOneShortcutParams {
-       BDeskWindow* window;
-       std::set<uint32>* currentAddonShortcuts;
-};
 
-static bool
-AddOneShortcut(const Model* model, const char*, uint32 shortcut,
-       bool /*primary*/, void* context)
+static void
+AddOneShortcut(Model* model, char key, uint32 modifiers, BDeskWindow* window)
 {
-       if (!shortcut)
-               // no shortcut, bail
-               return false;
-
-       AddOneShortcutParams* params = (AddOneShortcutParams*)context;
+       if (key == '\0')
+               return;
        BMessage* runAddon = new BMessage(kLoadAddOn);
        runAddon->AddRef("refs", model->EntryRef());
+       window->AddShortcut(key, modifiers, runAddon);
+}
 
-       params->window->AddShortcut(shortcut, B_OPTION_KEY | B_COMMAND_KEY,
-               runAddon);
-       params->currentAddonShortcuts->insert(shortcut);
-       PRINT(("adding new shortcut %c\n", (char)shortcut));
 
-       return false;
+
+static struct AddonShortcut*
+RevertToDefault(struct AddonShortcut* item, void* castToWindow)
+{
+       if (item->key != item->defaultKey || item->modifiers != 
kDefaultModifiers) {
+               BDeskWindow* window = static_cast<BDeskWindow*>(castToWindow);
+               if (window != NULL) {
+                       window->RemoveShortcut(item->key, item->modifiers);
+                       item->key = item->defaultKey;
+                       item->modifiers = kDefaultModifiers;
+                       AddOneShortcut(item->model, item->key, item->modifiers, 
window);
+               }
+       }
+       return 0;
+}
+
+
+static struct AddonShortcut*
+FindElement(struct AddonShortcut* item, void* castToOther)
+{
+       Model* other = static_cast<Model*>(castToOther);
+       if (*item->model->EntryRef() == *other->EntryRef())
+               return item;
+
+       return 0;
+}
+
+
+static void
+LoadAddOnDir(directory_which dirName, BDeskWindow* window,
+       LockingList<AddonShortcut>* list)
+{
+       BPath path;
+       if (find_directory(dirName, &path) == B_OK) {
+               path.Append("Tracker");
+               
+               BDirectory dir;
+               BEntry entry;
+
+               if (dir.SetTo(path.Path()) != B_OK)
+                       return;
+               
+               while (dir.GetNextEntry(&entry) == B_OK) {
+                       Model* model = new Model(&entry);
+                       if (model->InitCheck() == B_OK && model->IsSymLink()) {
+                               // resolve symlinks
+                               Model* resolved = new Model(model->EntryRef(), 
true, true);
+                               if (resolved->InitCheck() == B_OK)
+                                       model->SetLinkTo(resolved);
+                               else
+                                       delete resolved;
+                       }
+                       if (model->InitCheck() != B_OK
+                               || !model->ResolveIfLink()->IsExecutable()) {
+                               delete model;
+                               continue;
+                       }
+
+                       char* name = strdup(model->Name());
+                       if (!list->EachElement(MatchOne, name)) {
+                               struct AddonShortcut* item = new struct 
AddonShortcut;
+                               item->model = model;
+
+                               BResources 
resources(model->ResolveIfLink()->EntryRef());
+                               size_t size;
+                               char* shortcut = 
(char*)resources.LoadResource(B_STRING_TYPE,
+                                       kDefaultShortcut, &size);
+                               if (shortcut == NULL || strlen(shortcut) > 1)
+                                       item->key = '\0';
+                               else
+                                       item->key = shortcut[0];
+                               AddOneShortcut(model, item->key, 
kDefaultModifiers, window);
+                               item->defaultKey = item->key;
+                               list->AddItem(item);
+                       }
+                       free(name);
+               }
+
+               BNode node(path.Path());
+               node_ref nodeRef;
+               node.GetNodeRef(&nodeRef);
+       
+               TTracker::WatchNode(&nodeRef, B_WATCH_DIRECTORY, window);
+       }
 }
 
 
@@ -118,7 +194,8 @@ BDeskWindow::BDeskWindow(LockingList<BWindow>* windowList)
                        | B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS, 
B_ALL_WORKSPACES),
        fDeskShelf(0),
        fTrashContextMenu(0),
-       fShouldUpdateAddonShortcuts(true)
+       fNodeRef(NULL),
+       fShortcutsSettings(NULL)
 {
        // Add icon view switching shortcuts. These are displayed in the context
        // menu, although they obviously don't work from those menu items.
@@ -173,43 +250,133 @@ BDeskWindow::Init(const BMessage*)
                if (fDeskShelf)
                        fDeskShelf->SetDisplaysZombies(true);
        }
-
-       // watch add-on directories so that we can track the addons with
-       // corresponding shortcuts
-       WatchAddOnDir(B_USER_ADDONS_DIRECTORY, this);
-       WatchAddOnDir(B_COMMON_ADDONS_DIRECTORY, this);
-       WatchAddOnDir(B_SYSTEM_ADDONS_DIRECTORY, this);
+       InitKeyIndices();
+       InitAddonsList(false);
+       ApplyShortcutPreferences(false);
 
        _inherited::Init();
 }
 
 
 void
-BDeskWindow::MenusBeginning()
+BDeskWindow::InitAddonsList(bool update)
 {
-       _inherited::MenusBeginning();
-
-       if (fShouldUpdateAddonShortcuts) {
-               PRINT(("updating addon shortcuts\n"));
-               fShouldUpdateAddonShortcuts = false;
-
-               // remove all current addon shortcuts
-               for (std::set<uint32>::iterator it= 
fCurrentAddonShortcuts.begin();
-                       it != fCurrentAddonShortcuts.end(); it++) {
-                       PRINT(("removing shortcut %c\n", (int)*it));
-                       RemoveShortcut(*it, B_OPTION_KEY | B_COMMAND_KEY);
+       AutoLock<LockingList<AddonShortcut> > lock(fAddonsList);
+       if (lock.IsLocked()) {
+               if (update) {
+                       for (int i = fAddonsList->CountItems() - 1; i >= 0; 
i--) {
+                               AddonShortcut* item = fAddonsList->ItemAt(i);
+                               RemoveShortcut(item->key, B_OPTION_KEY | 
B_COMMAND_KEY);
+                       }
+                       fAddonsList->MakeEmpty(true);
                }
 
-               fCurrentAddonShortcuts.clear();
+               LoadAddOnDir(B_USER_ADDONS_DIRECTORY, this, fAddonsList);
+               LoadAddOnDir(B_COMMON_ADDONS_DIRECTORY, this, fAddonsList);
+               LoadAddOnDir(B_SYSTEM_ADDONS_DIRECTORY, this, fAddonsList);
+       }
+}
+
 
-               AddOneShortcutParams params;
-               params.window = this;
-               params.currentAddonShortcuts = &fCurrentAddonShortcuts;
+void
+BDeskWindow::ApplyShortcutPreferences(bool update)
+{
+       AutoLock<LockingList<AddonShortcut> > lock(fAddonsList);
+       if (lock.IsLocked()) {
+               if (!update) {
+                       BPath path;
+                       if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == 
B_OK) {
+                               BPathMonitor::StartWatching(path.Path(), 
B_WATCH_STAT | B_WATCH_FILES_ONLY, this);
+                               path.Append(kShortcutsSettings);
+                               fShortcutsSettings = new 
char[strlen(path.Path()) + 1];
+                               strcpy(fShortcutsSettings, path.Path());
+                       }
+               }
 
-               BObjectList<BString> mimeTypes(10, true);
-               BuildMimeTypeList(mimeTypes);
+               fAddonsList->EachElement(RevertToDefault, this);
 
-               EachAddon(&AddOneShortcut, &params, mimeTypes);
+               BFile shortcutSettings(fShortcutsSettings, B_READ_ONLY);
+               BMessage fileMsg;
+               if (shortcutSettings.InitCheck() != B_OK
+                       || fileMsg.Unflatten(&shortcutSettings) != B_OK) {
+                       fNodeRef = NULL;
+                       return;
+               }
+               shortcutSettings.GetNodeRef(fNodeRef);
+
+               int i = 0;
+               BMessage message;
+               while (fileMsg.FindMessage("spec", i++, &message) == B_OK) {
+       
+                       int32 key;
+                       BMessage actMsg;
+                       
+                       if (message.FindInt32("key", &key) == B_OK
+                               && message.FindMessage("act", &actMsg) == B_OK) 
{
+
+                               // only handle shortcuts referring add-ons
+                               BString command;
+                               if (actMsg.FindString("largv", &command) != 
B_OK)
+                                       continue;
+                               BPath path;
+                               bool isInAddons = false;
+                               if (find_directory(B_SYSTEM_ADDONS_DIRECTORY, 
&path)
+                                               == B_OK) {
+                                       path.Append("Tracker/");
+                                       isInAddons = 
command.FindFirst(path.Path()) == 0;
+                               }
+                               if (!isInAddons
+                                       && 
(find_directory(B_COMMON_ADDONS_DIRECTORY, &path)
+                                               == B_OK)) {
+                                       path.Append("Tracker/");
+                                       isInAddons = 
command.FindFirst(path.Path()) == 0;
+                               }
+                               if (!isInAddons
+                                       && 
(find_directory(B_USER_ADDONS_DIRECTORY, &path)
+                                               == B_OK)) {
+                                       path.Append("Tracker/");
+                                       isInAddons = 
command.FindFirst(path.Path()) == 0;
+                               }
+                               if (!isInAddons)
+                                       continue;
+
+                               BEntry entry(command);
+                               if (entry.InitCheck() != B_OK)
+                                       continue;
+
+                               const char* shortcut = GetKeyName(key);
+                               if (strlen(shortcut) != 1)
+                                       continue;
+                       
+                               uint32 modifiers = 0;
+                               int32 value;
+                               if (message.FindInt32("mcidx", 0, &value) == 
B_OK)
+                                       modifiers |= (value != 0 ? B_SHIFT_KEY 
: 0);
+
+                               if (message.FindInt32("mcidx", 1, &value) == 
B_OK)
+                                       modifiers |= (value != 0 ? 
B_CONTROL_KEY : 0);
+
+                               if (message.FindInt32("mcidx", 2, &value) == 
B_OK)
+                                       modifiers |= (value != 0 ? 
B_COMMAND_KEY : 0);
+
+                               if (message.FindInt32("mcidx", 3, &value) == 
B_OK)
+                                       modifiers |= (value != 0 ? B_OPTION_KEY 
: 0);
+
+                               if (modifiers == 0)
+                                       modifiers = kDefaultModifiers;
+
+                               Model model(&entry);
+                               AddonShortcut* item = 
fAddonsList->EachElement(FindElement,
+                                       &model);
+                               if (item != NULL) {
+                                       if (item->key != '\0')
+                                               RemoveShortcut(item->key, 
item->modifiers);
+                                       item->key = shortcut[0];
+                                       item->modifiers = modifiers;
+                                       AddOneShortcut(&model, item->key, 
item->modifiers, this);
+                               }
+                       }
+               }
        }
 }
 
@@ -228,6 +395,11 @@ BDeskWindow::Quit()
                fNavigationItem = 0;
        }
 
+       while (fAddonsList->CountItems())
+               fAddonsList->RemoveItem(0);
+
+       delete fAddonsList;
+
        delete fTrashContextMenu;
        fTrashContextMenu = NULL;
 
@@ -482,9 +654,28 @@ BDeskWindow::MessageReceived(BMessage* message)
        }
 
        switch (message->what) {
+               case B_PATH_MONITOR:
+               {
+                       const char* path = "";
+                       if (!(message->FindString("path", &path) == B_OK
+                                       && strcmp(path, fShortcutsSettings) == 
0)) {
+
+                               dev_t device;
+                               ino_t node;
+                               if (fNodeRef == NULL
+                                       || message->FindInt32("device", 
&device) != B_OK
+                                       || message->FindInt64("node", &node) != 
B_OK
+                                       || device != fNodeRef->device
+                                       || node != fNodeRef->node)
+                                       break;
+                       }
+                       ApplyShortcutPreferences(true);
+                       break;
+               }
                case B_NODE_MONITOR:
                        PRINT(("will update addon shortcuts\n"));
-                       fShouldUpdateAddonShortcuts = true;
+                       InitAddonsList(true);
+                       ApplyShortcutPreferences(true);
                        break;
 
                default:
diff --git a/src/kits/tracker/DeskWindow.h b/src/kits/tracker/DeskWindow.h
index d83a55a..8b670aa 100644
--- a/src/kits/tracker/DeskWindow.h
+++ b/src/kits/tracker/DeskWindow.h
@@ -75,24 +75,20 @@ protected:
        virtual BPoseView* NewPoseView(Model*, BRect, uint32);
 
        virtual void WorkspaceActivated(int32, bool);
-       virtual void MenusBeginning();
        virtual void MessageReceived(BMessage*);
 
 private:
+       void InitAddonsList(bool);
+       void ApplyShortcutPreferences(bool);
+
        BShelf* fDeskShelf;
                // shelf for replicant support
        BPopUpMenu* fTrashContextMenu;
 
        BRect fOldFrame;
 
-       // in the desktop window addon shortcuts have to be added by AddShortcut
-       // and we don't always get the MenusBeginning call to check for new
-       // addons/update the shortcuts -- instead we need to node monitor the
-       // addon directory and keep a dirty flag that triggers shortcut
-       // reinstallation
-       bool fShouldUpdateAddonShortcuts;
-       std::set<uint32> fCurrentAddonShortcuts;
-               // keeps track of which shortcuts are installed for Tracker 
addons
+       node_ref* fNodeRef;
+       char* fShortcutsSettings;
 
        typedef BContainerWindow _inherited;
 };
diff --git a/src/kits/tracker/Jamfile b/src/kits/tracker/Jamfile
index 248e9c3..bedab83 100644
--- a/src/kits/tracker/Jamfile
+++ b/src/kits/tracker/Jamfile
@@ -7,6 +7,8 @@ UsePrivateHeaders interface mount shared storage support 
tracker ;
 
 AddResources libtracker.so : TrackerIcons.rdef libtracker.rdef ;
 
+SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons input_server filters 
shortcut_catcher ] ;
+
 SubDirC++Flags
        -D_BUILDING_tracker=1
 #      -D_INCLUDES_CLASS_DEVICE_MAP=1
@@ -89,7 +91,8 @@ SharedLibrary libtracker.so :
        VolumeWindow.cpp
        WidgetAttributeText.cpp
 
-       : be translation $(vector_icon_libs) $(TARGET_LIBSTDC++) 
$(HAIKU_LOCALE_LIBS) libshared.a
+       : be translation $(vector_icon_libs) $(TARGET_LIBSTDC++) 
$(HAIKU_LOCALE_LIBS) libshared.a 
+               libshortcuts_shared.a 
        ;
 
 DoCatalogs libtracker.so :


Other related posts: