nathan-osman / NitroShare-Mac

Mac OS X project files and source code for building NitroShare.
3 stars 2 forks source link

Adding "System Tray" only mode #9

Closed mateosalta closed 11 years ago

mateosalta commented 11 years ago

I would like to add an option in the setting for the mac, that would enable a feature that lets NitroShare run with only the icon in the system tray, for those who like to run the program as an "always there standby".

Basically It needs to edit "Info.plist" that is inside the "app bundle" (the main program folder) to include an extra variable, http://www.macosxtips.co.uk/index_files/disable-the-dock-icon-for-any-application.php

So, I seem to have hit a wall in implementing this in the program. I made the Check box called SystemTray and added items in settings.h

// Load SystemTray configuration bool GetSystemTray(); void SetSystemTray(bool); }

And this to settings.cpp

`QDir GetNitroshareDir() {

QDir dir = QDir::home();
if(!dir.exists("Applications/NitroShare.app/Contents"))
    dir.mkpath("Applications/NitroShare.app/Contents");

dir.cd("Applications/NitroShare.app/Contents");
return dir.absolutePath();

}

void Settings::GetSystemTray() {

}

void Settings::SetSystemTray(bool load) { QString plist_file = dir.absolutePath(Info.plist);

if(load)

}`

All that needs to be done should be to find a way to read and write to the "Info.plist" file, possibly I might be going about this wrong.

Found this as a example of how to set the "LSUIElement" for having only the system tray icon, The code is way at the bottom (although more complex than needed, just need to extract the read/write function) http://lastfm.sourcearchive.com/documentation/1.3.0.62/settingsdialog_8cpp-source.html

It will take a bit, but I think this would make a great feature for the Mac Version, as this is something that is built into the system and just that file needs to be edited.

I'll continue looking into it, but if you have any insight it would help a lot.

mateosalta commented 11 years ago

I'm getting closer I found a better example to work on and have the check to see if "LSUIElement" is being used working, but it causes the settings "ok" and "cancel" buttons not to work.

At the end of settings.cpp I have

bool Settings::appHasDockIcon() { QProcess p; QString app = "/Applications/nitroshare.app/Contents/Info"; if (!QFile::exists(app + ".plist")); else

p.start("defaults", QStringList() << "read" << app << "LSUIElement");
p.waitForFinished();

if (p.exitCode() == 0)
    return p.readAllStandardOutput().trimmed() != "1";

else

return true;

}

not sure why. possibly because of "waitForFinished" the qt manual says "alling these functions from the main thread (the thread that calls QApplication::exec()) may cause your user interface to freeze." hm...

nathan-osman commented 11 years ago

I'm not sure I can be too much help here since I don't have access to a Mac. But I do see something wrong with the code above:

You are missing braces ({}) around the else clause. Also, the statement that follows the if is empty (the semicolon) and can be better written by inverting the condition. You probably wanted to do this:

bool Settings::appHasDockIcon()
{
    QString app("/Applications/nitroshare.app/Contents/Info");
    if (QFile::exists(app + ".plist"))
    {
        QProcess p;
        p.start("defaults", QStringList() << "read" << app << "LSUIElement");
        p.waitForFinished();

        if (p.exitCode() == 0)
            return p.readAllStandardOutput().trimmed() != "1";
    }
    return true;
}

Hopefully that helps things out a bit.

mateosalta commented 11 years ago

Looks awesome, the code is much better, but calling QProcess still freezes the ok and cancel buttons, I've been trying to research some solutions, one may be using QThread or something, much discussion here http://comments.gmane.org/gmane.comp.lib.qt.general/17792

or this seems interesting, http://www.thomaskeller.biz/blog/2008/05/07/hide-qt-gui-applications-from-the-mac-os-x-dock-and-menu/

Can qt edit other settings files with QSettings? I know it reads and writes to a .plist for it's regular, maybe there is a built in way that would make it so I don't need to use QProcess.

mateosalta commented 11 years ago

Oh, never-mind about that, seams I'm doing it wrong. I figured out the freezing button problem and started on the code to write the variable to Info.plist, right now It is only working one way, Either removing or adding the variable(depending if I change the places of the "1" and "0", so I think I have the If Else statements messed up (the last part) again...

Here is what I have so far, (the other bits of code follow the pattern of the LoadAtStartup)

bool Settings::GetSystemTray()
{
        QString app("/Applications/nitroshare.app/Contents/Info");
        if (QFile::exists(app + ".plist"))
        {
                QProcess p;
                 p.start("defaults", QStringList() << "read" << app << "LSUIElement");
            p.waitForFinished(); 

            if (p.exitCode() == 0)
                return p.readAllStandardOutput().trimmed() != "0";
        }
    return true;
}

void Settings::SetSystemTray(bool load) 
{   
    QString app("/Applications/nitroshare.app/Contents/Info");

     if(load)
        {
            QProcess p;
            p.start("defaults", QStringList() << "write" << app << "LSUIElement" << "0");
            p.waitForFinished();

            p.start("touch", QStringList() << "/Applications/nitroshare.app/");
        }
        QProcess p;
        p.start("defaults", QStringList() << "write" << app << "LSUIElement" << "1");
        p.waitForFinished();

        p.start( "touch", QStringList() << "/Applications/nitroshare.app/" );
      }
nathan-osman commented 11 years ago

Try this:

void Settings::SetSystemTray(bool load) 
{
    QString app("/Applications/nitroshare.app/Contents/Info");

    QProcess p;
    p.start("defaults", QStringList() << "write" << app << "LSUIElement" << (load?"0":"1"));
    p.waitForFinished();

    p.start("touch", QStringList() << "/Applications/nitroshare.app/");
    p.waitForFinished();
}
mateosalta commented 11 years ago

Awesome, Thank you for the coding help. The new feature is now implemented.