make it possible to bring the calling process to front

This commit is contained in:
Patrick von Reth 2015-04-04 14:50:52 +02:00
parent 204528e09a
commit 87f6bdfcc5
2 changed files with 65 additions and 8 deletions

View File

@ -7,17 +7,12 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
include(GenerateExportHeader) include(GenerateExportHeader)
set(SNORE_VERSION_MAJOR 0)
set(SNORE_VERSION_MINOR 1)
set(SNORE_VERSION_PATCH 0)
set(SNORE_VERSION_SUFFIX "alpha")
find_package(ECM 0.0.9 NO_MODULE) find_package(ECM 0.0.9 NO_MODULE)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH}) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH})
include(KDECompilerSettings) include(KDECompilerSettings)
find_package(LibsnoreQt5 REQUIRED) find_package(LibsnoreQt5 0.5.91 REQUIRED)

View File

@ -9,13 +9,67 @@
#include <iostream> #include <iostream>
#ifdef Q_OS_WIN
#include <windows.h>
#include <windowsx.h>
#include <shellapi.h>
#include <winuser.h>
#endif
using namespace Snore; using namespace Snore;
using namespace std;
void bringToFront(QString pid, Notification noti)
{
Q_UNUSED(pid)
Q_UNUSED(noti)
#ifdef Q_OS_WIN
auto findWindowForPid = [](ulong pid)
{
// based on http://stackoverflow.com/a/21767578
pair<ulong, HWND> data = make_pair(pid, (HWND)0);
::EnumWindows([](HWND handle, LPARAM lParam) -> BOOL{
auto isMainWindow = [](HWND handle){
return ::GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(handle);
};
pair<ulong, HWND>& data = *(pair<ulong, HWND>*)lParam;
ulong process_id = 0;
::GetWindowThreadProcessId(handle, &process_id);
if (data.first != process_id || !isMainWindow(handle)) {
return TRUE;
}
data.second = handle;
return FALSE;
}, (LPARAM)&data);
return data.second;
};
HWND wid = findWindowForPid(pid.toInt());
if(wid) {
HWND hwndActiveWin = GetForegroundWindow();
int idActive = GetWindowThreadProcessId( hwndActiveWin, NULL );
if ( AttachThreadInput(GetCurrentThreadId(), idActive, TRUE) )
{
SetForegroundWindow( wid );
SetFocus( wid );
FlashWindow( wid, TRUE );
AttachThreadInput( GetCurrentThreadId(), idActive, FALSE );
} else {
// try it anyhow
SetForegroundWindow( wid );
SetFocus( wid );
FlashWindow( wid, TRUE );
}
}
#endif
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QApplication app(argc, argv); QApplication app(argc, argv);
app.setApplicationName("snore-send"); app.setApplicationName("snore-send");
app.setOrganizationName("snore-send"); app.setOrganizationName("Snorenotify");
app.setApplicationVersion(Snore::Version::version()); app.setApplicationVersion(Snore::Version::version());
QCommandLineParser parser; QCommandLineParser parser;
@ -41,6 +95,11 @@ int main(int argc, char *argv[])
QCommandLineOption silent(QStringList() << "silent", "Don't print to stdout."); QCommandLineOption silent(QStringList() << "silent", "Don't print to stdout.");
parser.addOption(silent); parser.addOption(silent);
QCommandLineOption _bringToFront(QStringList() << "bring-to-front", "Bring process with pid to front if notification is clicked.", "pid");
parser.addOption(_bringToFront);
parser.process(app); parser.process(app);
if (parser.isSet(title) && parser.isSet(message)) { if (parser.isSet(title) && parser.isSet(message)) {
SnoreCore &core = SnoreCore::instance(); SnoreCore &core = SnoreCore::instance();
@ -63,7 +122,10 @@ int main(int argc, char *argv[])
if (!parser.isSet(silent)) { if (!parser.isSet(silent)) {
QString reason; QString reason;
QDebug(&reason) << noti.closeReason(); QDebug(&reason) << noti.closeReason();
std::cout << qPrintable(reason) << std::endl; cout << qPrintable(reason) << endl;
}
if(noti.closeReason() == Notification::CLOSED && parser.isSet(_bringToFront)) {
bringToFront(parser.value(_bringToFront), noti);
} }
returnCode = noti.closeReason(); returnCode = noti.closeReason();
}); });