Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
cmake_minimum_required(VERSION 3.1)
project (activityfox)


cmake_policy(SET CMP0059 NEW)

find_package(KDE4 REQUIRED)
include_directories(${KDE4_INCLUDES})

set(tutorial2_SRCS
main.cpp
set(SOURCE_FILES
src/main.cpp
src/BrowserManager.h
src/BrowserManager.cpp
src/FirefoxManager.h
src/FirefoxManager.cpp
src/ChromiumManager.h
src/ChromiumManager.cpp
src/GoogleChromeManager.h
src/GoogleChromeManager.cpp
)

kde4_add_executable(activityfox ${tutorial2_SRCS})
target_link_libraries(activityfox ${KDE4_KDEUI_LIBS})
kde4_add_executable(activityfox ${SOURCE_FILES})
target_link_libraries(activityfox ${KDE4_KDEUI_LIBS})

set_property(TARGET activityfox PROPERTY CXX_STANDARD 11)
99 changes: 0 additions & 99 deletions README

This file was deleted.

91 changes: 91 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
## Description

ActivityFox is a small KDE program that acts as a workaround to allow Firefox, Google Chrome and Chromium-based browsers to
play nice with KDE Plasma Activities.

ActivityFox lets you use separate browser instances for each activity, keeping tabs related to that activity. ActivityFox starts the browser with a profile linked to your current activity, closes the browser when you close the activity and automatically restores it when you open it again.

## Usage

When run without specifying command line arguments, ActivityFox starts Firefox with a profile named as your current activity id, creating it in a default profile directory if it doesn't exist.

To launch Google Chrome or Chromium with a profile linked to your current activity, use the following commands:

```bash
activityfox --google-chrome
activityfox --chromium
```

If your browser is located in a location different from the default one, you should specify the location of a binary file:

```bash
activityfox --google-chrome --bin-path /usr/lib/firefox/firefox
activityfox --google-chrome --bin-path /opt/google/chrome/google-chrome
activityfox --chromium --bin-path /usr/lib/chromium-browser/chromium-browser
```
In case your profiles are located in a different directory:

```bash
activityfox --google-chrome --profile-dir /home/<user>/.mozilla/firefox
activityfox --google-chrome --profile-dir /home/<user>/.config/google-chrome
activityfox --chromium --profile-dir /home/<user>/.config/chromium
```

If you want to launch your browser with a specific profile, use:

```bash
activityfox profile_name
```
To make ActivityFox create profiles for new activities based on a template profile, first create it:

```bash
activityfox template_profile_name
```

Set it up by making your browser show tabs from the last time, then use this command to automatically create new profiles based on your template:

```bash
activityfox --template-profile-name template_profile_name
```

You may create a desktop file with this command and place it on your desktop or in your launcher menu. This way, in every new activity, you will be able to open a browser instance linked to that activity with an automatically created profile based on your template.

## Hide ActivityFox window

Creating a visible window is required to make the session manager call our application on session saving, but it's possible to hide it with KWin rules.

Right-click the title-bar of the window, select More Actions > Special Application Settings.
In the window rules settings that pop up, set:

- Size & Position > Minimized to Apply Initially, Yes
- Arrangement & Access > Skip Taskbar to Apply initially, Yes
- Arrangement & Access > Skip Pager to Apply initially, Yes
- Arrangement & Access > Skip Switcher to Apply initially, Yes

## Build

~~~bash
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
~~~

That should give you the 'activityfox' executable in the build folder.

## Changelog

### 0.2
- Add Google Chrome and Chromium support
- ActivityFox automatically opens the browser with a profile linked to the current activity id
- ActivityFox gently closes browsers by sending a signal to close the window, mitigating crashes
- Creation of new profiles based on a template profile
- ActivityFox restores browsers in activites they were initially launched

### 0.1
- ActivityFox launches Firefox and terminates it on session saving, restores on session start

## License

GPL v3
Copyright [2012 Yuen Hoe (Jason moofang)](http://yuenhoe.com/blog/2012/08/associating-firefox-profiles-with-kde-activities/), 2018 Leonid Kalichkin (hellishnoob)
79 changes: 0 additions & 79 deletions main.cpp

This file was deleted.

72 changes: 72 additions & 0 deletions src/BrowserManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "BrowserManager.h"

BrowserManager::BrowserManager(const QString &startUpActivityId, const QString &binPath,
const QString &profileDir, const QString &templateProfileName,
const QString &profileName) {
this->startUpActivityId = startUpActivityId;
this->binPath = binPath;
this->profileDir = profileDir;
this->templateProfileName = templateProfileName;
this->profileName = profileName;
}

void BrowserManager::init() {
if (binPath == nullptr || binPath == "") {
binPath = getDefaultBinPath();
}

if (profileDir == nullptr || profileDir == "") {
profileDir = getDefaultProfileDir();
}

// if profile name was not specified, use current activity id
if (profileName == nullptr || profileName == "") {
profileName = startUpActivityId;
}

if (!checkIfProfileExists(profileDir, profileName)) {
qDebug() << "Profile doesn't exist, creating it, name is: " << profileName;
createProfile(binPath, profileDir, profileName, templateProfileName);
}

qDebug() << "Starting the browser";
startBrowser(process, binPath, profileDir, profileName);
}

// expects a non-zero pid, so the process must be running
void BrowserManager::closeBrowser(KProcess &process) {
char pid[21];
KProcess closeBrowser;

sprintf(pid, "%d", process.pid());
QString command = "wmctrl -i -c `wmctrl -lp | grep " + QString(pid) + " | cut -c -10`";
qDebug() << command;

// trying to gracefully terminate the browser by closing the window with wmctrl
closeBrowser.setShellCommand(command);
int exitcode = closeBrowser.execute();

// if wmctrl failed, terminate the browser normally
if (exitcode != 0) {
qDebug() << "wmctrl failed";
process.terminate();
}

// wait until the browser is closed for at most 30 seconds, terminate if it wasn't closed after that
if (!process.waitForFinished()) {
qDebug() << "The browser hasn't finished in 30 seconds";
process.terminate();
}
}


void BrowserManager::onSaveProperties() {
qDebug() << "onSaveProperties() was called";

if (process.pid() > 0) {
closeBrowser(process);
} else {
// the browser was closed by user or unexpectedly, so we don't want to restore it automatically
exit(0);
}
}
Loading