AutoRaise: Properly load tray icon bitmap
AutoRaise needs to load bitmaps stored as resources in the AppRaise image. The strategy it used before was to store the path to itself in its settings file. It stored the entry_ref to the image in the settings, which may not be stable across reboots with packagefs. In addition, the path could change at some point for any other reason. This patch changes AutoRaise to just use the same method as other tray applets, which is to search the process for the image containing the AutoRaise code, and then to get the path from the image_info. Most of the initialization work is performed by TrayView::_init(), which is called by the constructor. Some of the operations performed by this method can fail, leaving TrayView partially initialized. Any error is handled by returning early after telling Deskbar to remove this item so that it will not continue running in a partially initialized state. Deskbar will invoke the destructor so even a partially initialized TrayView will be cleaned up. Fixes #16473 Change-Id: Id1ac1ef78d410a7d191cfe88f1ba1db30e258adc Reviewed-on: https://review.haiku-os.org/c/haiku/+/3341 Reviewed-by: Jérôme Duval <[email protected]>
This commit is contained in:
@@ -15,16 +15,6 @@ AutoRaiseApp::AutoRaiseApp()
|
||||
removeFromDeskbar(NULL);
|
||||
fPersist = true;
|
||||
fDone = false;
|
||||
|
||||
//since the tray item shows an icon, and the class TrayView needs to be
|
||||
//able to know the location of the executing binary, we write into the
|
||||
//settings file this critical information when the app is fired up
|
||||
app_info info;
|
||||
be_app->GetAppInfo(&info);
|
||||
|
||||
//now, put the path into the settings file
|
||||
AutoRaiseSettings settings;
|
||||
settings.SetAppPath(info.ref);
|
||||
}
|
||||
|
||||
AutoRaiseApp::~AutoRaiseApp()
|
||||
|
||||
@@ -31,6 +31,21 @@ status_t removeFromDeskbar(void *)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
our_image(image_info& image)
|
||||
{
|
||||
int32 cookie = 0;
|
||||
while (get_next_image_info(B_CURRENT_TEAM, &cookie, &image) == B_OK) {
|
||||
if ((char *)our_image >= (char *)image.text
|
||||
&& (char *)our_image <= (char *)image.text + image.text_size)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
//**************************************************
|
||||
|
||||
ConfigMenu::ConfigMenu(TrayView *tv, bool useMag)
|
||||
@@ -201,13 +216,10 @@ void TrayView::GetPreferredSize(float *w, float *h)
|
||||
void TrayView::_init()
|
||||
{
|
||||
thread_info ti;
|
||||
status_t err;
|
||||
|
||||
watching = false;
|
||||
_settings = new AutoRaiseSettings;
|
||||
|
||||
_appPath = _settings->AppPath();
|
||||
|
||||
raise_delay = _settings->Delay();
|
||||
current_window = 0;
|
||||
polling_delay = 100000;
|
||||
@@ -224,16 +236,31 @@ void TrayView::_init()
|
||||
resume_thread(poller_thread = spawn_thread(poller, "AutoRaise desktop "
|
||||
"poller", B_NORMAL_PRIORITY, (void *)this));
|
||||
|
||||
//determine paths to icon files based on app path in settings file
|
||||
image_info info;
|
||||
{
|
||||
status_t result = our_image(info);
|
||||
if (result != B_OK) {
|
||||
printf("Unable to lookup image_info for the AutoRaise image: %s\n",
|
||||
strerror(result));
|
||||
removeFromDeskbar(NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BResources res;
|
||||
BFile theapp(&_appPath, B_READ_ONLY);
|
||||
if ((err = res.SetTo(&theapp)) != B_OK) {
|
||||
BFile file(info.name, B_READ_ONLY);
|
||||
if (file.InitCheck() != B_OK) {
|
||||
printf("Unable to access AutoRaise image file: %s\n",
|
||||
strerror(file.InitCheck()));
|
||||
removeFromDeskbar(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Unable to find the app to get the resources !!!\n");
|
||||
// removeFromDeskbar(NULL);
|
||||
// delete _settings;
|
||||
// return;
|
||||
BResources res(&file);
|
||||
if (res.InitCheck() != B_OK) {
|
||||
printf("Unable to load image resources: %s\n",
|
||||
strerror(res.InitCheck()));
|
||||
removeFromDeskbar(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t bmsz;
|
||||
@@ -242,19 +269,22 @@ void TrayView::_init()
|
||||
p = (char *)res.LoadResource('MICN', ACTIVE_ICON, &bmsz);
|
||||
_activeIcon = new BBitmap(BRect(0, 0, B_MINI_ICON-1, B_MINI_ICON -1),
|
||||
B_CMAP8);
|
||||
if (!p)
|
||||
if (p == NULL) {
|
||||
puts("ERROR loading active icon");
|
||||
else
|
||||
_activeIcon->SetBits(p, B_MINI_ICON*B_MINI_ICON, 0, B_CMAP8);
|
||||
removeFromDeskbar(NULL);
|
||||
return;
|
||||
}
|
||||
_activeIcon->SetBits(p, B_MINI_ICON * B_MINI_ICON, 0, B_CMAP8);
|
||||
|
||||
p = (char *)res.LoadResource('MICN', INACTIVE_ICON, &bmsz);
|
||||
_inactiveIcon = new BBitmap(BRect(0, 0, B_MINI_ICON-1, B_MINI_ICON -1),
|
||||
B_CMAP8);
|
||||
if (!p)
|
||||
if (p == NULL) {
|
||||
puts("ERROR loading inactive icon");
|
||||
else
|
||||
_inactiveIcon->SetBits(p, B_MINI_ICON*B_MINI_ICON, 0, B_CMAP8);
|
||||
|
||||
removeFromDeskbar(NULL);
|
||||
return;
|
||||
}
|
||||
_inactiveIcon->SetBits(p, B_MINI_ICON * B_MINI_ICON, 0, B_CMAP8);
|
||||
|
||||
SetDrawingMode(B_OP_ALPHA);
|
||||
SetFlags(Flags() | B_WILL_DRAW);
|
||||
@@ -281,12 +311,8 @@ TrayView::~TrayView(){
|
||||
|
||||
//Dehydrate into a message (called by the DeskBar)
|
||||
status_t TrayView::Archive(BMessage *data, bool deep) const {
|
||||
// BEntry appentry(&_appPath, true);
|
||||
// BPath appPath(&appentry);
|
||||
status_t error=BView::Archive(data, deep);
|
||||
data->AddString("add_on", APP_SIG);
|
||||
// data->AddFlat("_appPath", (BFlattenable *) &_appPath);
|
||||
data->AddRef("_appPath", &_appPath);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ class TrayView:public BView{
|
||||
private:
|
||||
|
||||
BBitmap *_activeIcon, *_inactiveIcon;
|
||||
entry_ref _appPath;
|
||||
bool watching;
|
||||
|
||||
void _init(void); //initialization common to all constructors
|
||||
|
||||
@@ -16,8 +16,6 @@ _type AutoRaiseSettings::_name()\
|
||||
CONF_ADDPROP(bool, Active)
|
||||
CONF_ADDPROP(bigtime_t, Delay)
|
||||
CONF_ADDPROP(int32, Mode)
|
||||
//CONF_ADDPROP(BPath, AppPath)
|
||||
CONF_ADDPROP(entry_ref, AppPath)
|
||||
#undef CONF_ADDPROP
|
||||
|
||||
AutoRaiseSettings::AutoRaiseSettings()
|
||||
@@ -42,12 +40,6 @@ AutoRaiseSettings::AutoRaiseSettings()
|
||||
|
||||
if (_settingsMessage.FindInt32(AR_MODE, &_confMode) != B_OK)
|
||||
printf("AutoRaiseSettings::AutoRaiseSettings();\tFailed to load mode from settings file. Using default\n");
|
||||
|
||||
// if (_settingsMessage.FindFlat(AR_APP_PATH, (BFlattenable *) &_appPath) != B_OK)
|
||||
// printf("AutoRaiseSettings::AutoRaiseSettings();\tFailed to load application path.\n");
|
||||
|
||||
if (_settingsMessage.FindRef(AR_APP_PATH, &_confAppPath) != B_OK)
|
||||
printf("AutoRaiseSettings::AutoRaiseSettings();\tFailed to load application path.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -73,8 +65,6 @@ AutoRaiseSettings::~AutoRaiseSettings()
|
||||
_settingsMessage.AddBool(AR_ACTIVE, _confActive);
|
||||
_settingsMessage.AddInt64(AR_DELAY, _confDelay);
|
||||
_settingsMessage.AddInt32(AR_MODE, _confMode);
|
||||
// _settingsMessage.AddFlat(AR_APP_PATH, &_appPath);
|
||||
_settingsMessage.AddRef(AR_APP_PATH, &_confAppPath);
|
||||
|
||||
//write message to settings file
|
||||
if (_settingsMessage.Flatten(&_settingsFile) != B_OK)
|
||||
|
||||
@@ -40,8 +40,6 @@ class AutoRaiseSettings
|
||||
{
|
||||
protected:
|
||||
BFile _settingsFile;
|
||||
// BPath _appPath;
|
||||
|
||||
BMessage _settingsMessage;
|
||||
|
||||
|
||||
@@ -56,13 +54,9 @@ class AutoRaiseSettings
|
||||
CONF_ADDPROP(bool, Active)
|
||||
CONF_ADDPROP(bigtime_t, Delay)
|
||||
CONF_ADDPROP(int32, Mode)
|
||||
//CONF_ADDPROP(BPath, AppPath)
|
||||
CONF_ADDPROP(entry_ref, AppPath)
|
||||
|
||||
};
|
||||
|
||||
#undef CONF_ADDPROP
|
||||
|
||||
#define AR_APP_PATH "ar:app_path"
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user