mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Use AssocQueryString
instead of directly querying the registry (#4362)
Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
parent
d38187f794
commit
1d3ca0bfa3
|
@ -47,6 +47,7 @@
|
||||||
- Dev: Added CMake Install Support on Windows. (#4300)
|
- Dev: Added CMake Install Support on Windows. (#4300)
|
||||||
- Dev: Changed conan generator to [`CMakeDeps`](https://docs.conan.io/en/latest/reference/conanfile/tools/cmake/cmakedeps.html) and [`CMakeToolchain`](https://docs.conan.io/en/latest/reference/conanfile/tools/cmake/cmaketoolchain.html). See PR for migration notes. (#4335)
|
- Dev: Changed conan generator to [`CMakeDeps`](https://docs.conan.io/en/latest/reference/conanfile/tools/cmake/cmakedeps.html) and [`CMakeToolchain`](https://docs.conan.io/en/latest/reference/conanfile/tools/cmake/cmaketoolchain.html). See PR for migration notes. (#4335)
|
||||||
- Dev: Refactored 7TV EventAPI implementation. (#4342)
|
- Dev: Refactored 7TV EventAPI implementation. (#4342)
|
||||||
|
- Dev: Don't rely on undocumented registry keys to find the default browser on Windows. (#4362)
|
||||||
|
|
||||||
## 2.4.0
|
## 2.4.0
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
#include "util/IncognitoBrowser.hpp"
|
#include "util/IncognitoBrowser.hpp"
|
||||||
|
#ifdef USEWINSDK
|
||||||
|
# include "util/WindowsHelper.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QSettings>
|
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using namespace chatterino;
|
using namespace chatterino;
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef USEWINSDK
|
||||||
QString injectPrivateSwitch(QString command)
|
QString injectPrivateSwitch(QString command)
|
||||||
{
|
{
|
||||||
// list of command line switches to turn on private browsing in browsers
|
// list of command line switches to turn on private browsing in browsers
|
||||||
|
@ -47,23 +49,27 @@ QString injectPrivateSwitch(QString command)
|
||||||
|
|
||||||
QString getCommand()
|
QString getCommand()
|
||||||
{
|
{
|
||||||
// get default browser prog id
|
// get default browser start command, by protocol if possible, falling back to extension if not
|
||||||
auto browserId = QSettings("HKEY_CURRENT_"
|
QString command =
|
||||||
"USER\\Software\\Microsoft\\Windows\\Shell\\"
|
getAssociatedCommand(AssociationQueryType::Protocol, L"http");
|
||||||
"Associations\\UrlAssociatio"
|
|
||||||
"ns\\http\\UserChoice",
|
|
||||||
QSettings::NativeFormat)
|
|
||||||
.value("Progid")
|
|
||||||
.toString();
|
|
||||||
|
|
||||||
// get default browser start command
|
|
||||||
auto command =
|
|
||||||
QSettings("HKEY_CLASSES_ROOT\\" + browserId + "\\shell\\open\\command",
|
|
||||||
QSettings::NativeFormat)
|
|
||||||
.value("Default")
|
|
||||||
.toString();
|
|
||||||
if (command.isNull())
|
if (command.isNull())
|
||||||
{
|
{
|
||||||
|
// failed to fetch default browser by protocol, try by file extension instead
|
||||||
|
command =
|
||||||
|
getAssociatedCommand(AssociationQueryType::FileExtension, L".html");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.isNull())
|
||||||
|
{
|
||||||
|
// also try the equivalent .htm extension
|
||||||
|
command =
|
||||||
|
getAssociatedCommand(AssociationQueryType::FileExtension, L".htm");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.isNull())
|
||||||
|
{
|
||||||
|
// failed to find browser command
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +90,7 @@ namespace chatterino {
|
||||||
|
|
||||||
bool supportsIncognitoLinks()
|
bool supportsIncognitoLinks()
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef USEWINSDK
|
||||||
return !getCommand().isNull();
|
return !getCommand().isNull();
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
|
@ -93,7 +99,7 @@ bool supportsIncognitoLinks()
|
||||||
|
|
||||||
bool openLinkIncognito(const QString &link)
|
bool openLinkIncognito(const QString &link)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef USEWINSDK
|
||||||
auto command = getCommand();
|
auto command = getCommand();
|
||||||
|
|
||||||
// TODO: split command into program path and incognito argument
|
// TODO: split command into program path and incognito argument
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
#ifdef USEWINSDK
|
#ifdef USEWINSDK
|
||||||
|
|
||||||
|
# include <Shlwapi.h>
|
||||||
|
# include <VersionHelpers.h>
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
typedef enum MONITOR_DPI_TYPE {
|
typedef enum MONITOR_DPI_TYPE {
|
||||||
|
@ -17,6 +20,8 @@ typedef enum MONITOR_DPI_TYPE {
|
||||||
|
|
||||||
typedef HRESULT(CALLBACK *GetDpiForMonitor_)(HMONITOR, MONITOR_DPI_TYPE, UINT *,
|
typedef HRESULT(CALLBACK *GetDpiForMonitor_)(HMONITOR, MONITOR_DPI_TYPE, UINT *,
|
||||||
UINT *);
|
UINT *);
|
||||||
|
typedef HRESULT(CALLBACK *AssocQueryString_)(ASSOCF, ASSOCSTR, LPCWSTR, LPCWSTR,
|
||||||
|
LPWSTR, DWORD *);
|
||||||
|
|
||||||
boost::optional<UINT> getWindowDpi(HWND hwnd)
|
boost::optional<UINT> getWindowDpi(HWND hwnd)
|
||||||
{
|
{
|
||||||
|
@ -83,6 +88,67 @@ void setRegisteredForStartup(bool isRegistered)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString getAssociatedCommand(AssociationQueryType queryType, LPCWSTR query)
|
||||||
|
{
|
||||||
|
static HINSTANCE shlwapi = LoadLibrary(L"shlwapi");
|
||||||
|
if (shlwapi == nullptr)
|
||||||
|
{
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto assocQueryString =
|
||||||
|
AssocQueryString_(GetProcAddress(shlwapi, "AssocQueryStringW"));
|
||||||
|
if (assocQueryString == nullptr)
|
||||||
|
{
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// always error out instead of returning a truncated string when the
|
||||||
|
// buffer is too small - avoids race condition when the user changes their
|
||||||
|
// default browser between calls to AssocQueryString
|
||||||
|
ASSOCF flags = ASSOCF_NOTRUNCATE;
|
||||||
|
|
||||||
|
if (queryType == AssociationQueryType::Protocol)
|
||||||
|
{
|
||||||
|
// ASSOCF_IS_PROTOCOL was introduced in Windows 8
|
||||||
|
if (IsWindows8OrGreater())
|
||||||
|
{
|
||||||
|
flags |= ASSOCF_IS_PROTOCOL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD resultSize = 0;
|
||||||
|
if (FAILED(assocQueryString(flags, ASSOCSTR_COMMAND, query, nullptr,
|
||||||
|
nullptr, &resultSize)))
|
||||||
|
{
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resultSize <= 1)
|
||||||
|
{
|
||||||
|
// resultSize includes the null terminator. if resultSize is 1, the
|
||||||
|
// returned value would be the empty string.
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString result;
|
||||||
|
auto buf = new wchar_t[resultSize];
|
||||||
|
if (SUCCEEDED(assocQueryString(flags, ASSOCSTR_COMMAND, query, nullptr, buf,
|
||||||
|
&resultSize)))
|
||||||
|
{
|
||||||
|
// QString::fromWCharArray expects the length in characters *not
|
||||||
|
// including* the null terminator, but AssocQueryStringW calculates
|
||||||
|
// length including the null terminator
|
||||||
|
result = QString::fromWCharArray(buf, resultSize - 1);
|
||||||
|
}
|
||||||
|
delete[] buf;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,12 +7,16 @@
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
|
enum class AssociationQueryType { Protocol, FileExtension };
|
||||||
|
|
||||||
boost::optional<UINT> getWindowDpi(HWND hwnd);
|
boost::optional<UINT> getWindowDpi(HWND hwnd);
|
||||||
void flushClipboard();
|
void flushClipboard();
|
||||||
|
|
||||||
bool isRegisteredForStartup();
|
bool isRegisteredForStartup();
|
||||||
void setRegisteredForStartup(bool isRegistered);
|
void setRegisteredForStartup(bool isRegistered);
|
||||||
|
|
||||||
|
QString getAssociatedCommand(AssociationQueryType queryType, LPCWSTR query);
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue