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)
This commit is contained in:
@@ -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)
|
||||
{
|
||||
@@ -218,7 +178,7 @@ CompareLabels(const BMenuItem* item1, const BMenuItem* item2)
|
||||
|
||||
static bool
|
||||
AddOneAddon(const Model* model, const char* name, uint32 shortcut,
|
||||
bool primary, void* context)
|
||||
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,61 +2879,17 @@ BContainerWindow::AddTrashContextMenus(BMenu* menu)
|
||||
|
||||
void
|
||||
BContainerWindow::EachAddon(bool (*eachAddon)(const Model*, const char*,
|
||||
uint32 shortcut, bool primary, void* context), void* passThru,
|
||||
BObjectList<BString> &mimeTypes)
|
||||
uint32 shortcut, uint32 modifiers, 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)
|
||||
{
|
||||
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
|
||||
|
||||
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(&entry, B_READ_ONLY);
|
||||
BFile file(item->model->EntryRef(), B_READ_ONLY);
|
||||
if (file.InitCheck() == B_OK) {
|
||||
BAppFileInfo info(&file);
|
||||
if (info.InitCheck() == B_OK) {
|
||||
@@ -2984,7 +2900,8 @@ BContainerWindow::EachAddon(BPath &path, bool (*eachAddon)(const Model*,
|
||||
if (info.GetSupportedTypes(&message) == B_OK) {
|
||||
type_code type;
|
||||
int32 count;
|
||||
if (message.GetInfo("types", &type, &count) == B_OK)
|
||||
if (message.GetInfo("types", &type,
|
||||
&count) == B_OK)
|
||||
secondary = false;
|
||||
}
|
||||
|
||||
@@ -3003,30 +2920,15 @@ BContainerWindow::EachAddon(BPath &path, bool (*eachAddon)(const Model*,
|
||||
}
|
||||
}
|
||||
|
||||
if (!secondary && !primary) {
|
||||
delete model;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
+245
-54
@@ -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,47 +67,120 @@ 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 struct AddonShortcut*
|
||||
MatchOne(struct AddonShortcut* item, void* castToName)
|
||||
{
|
||||
if (strcmp(item->model->Name(), (const char*)castToName) == 0) {
|
||||
// found match, bail out
|
||||
return item;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
WatchAddOnDir(directory_which dirName, BDeskWindow* window)
|
||||
AddOneShortcut(Model* model, char key, uint32 modifiers, BDeskWindow* window)
|
||||
{
|
||||
if (key == '\0')
|
||||
return;
|
||||
BMessage* runAddon = new BMessage(kLoadAddOn);
|
||||
runAddon->AddRef("refs", model->EntryRef());
|
||||
window->AddShortcut(key, modifiers, runAddon);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct AddOneShortcutParams {
|
||||
BDeskWindow* window;
|
||||
std::set<uint32>* currentAddonShortcuts;
|
||||
};
|
||||
|
||||
static bool
|
||||
AddOneShortcut(const Model* model, const char*, uint32 shortcut,
|
||||
bool /*primary*/, void* context)
|
||||
{
|
||||
if (!shortcut)
|
||||
// no shortcut, bail
|
||||
return false;
|
||||
|
||||
AddOneShortcutParams* params = (AddOneShortcutParams*)context;
|
||||
BMessage* runAddon = new BMessage(kLoadAddOn);
|
||||
runAddon->AddRef("refs", model->EntryRef());
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
@@ -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;
|
||||
|
||||
BObjectList<BString> mimeTypes(10, true);
|
||||
BuildMimeTypeList(mimeTypes);
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
EachAddon(&AddOneShortcut, ¶ms, mimeTypes);
|
||||
fAddonsList->EachElement(RevertToDefault, this);
|
||||
|
||||
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:
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -90,6 +92,7 @@ SharedLibrary libtracker.so :
|
||||
WidgetAttributeText.cpp
|
||||
|
||||
: be translation $(vector_icon_libs) $(TARGET_LIBSTDC++) $(HAIKU_LOCALE_LIBS) libshared.a
|
||||
libshortcuts_shared.a
|
||||
;
|
||||
|
||||
DoCatalogs libtracker.so :
|
||||
|
||||
Reference in New Issue
Block a user