mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-22 01:06:03 +03:00
Fixed mac specific compiler errors and cleaned up Objective C code
Created new file src/gui/macutilities.mm, moved code from mainwindow.cpp and torrentcontentmodel.cpp that used the Objective C runtime into it and converted it to actual Objective C. Rewrote pixmapForExtension() so that it doesn't call into private Qt functions.
This commit is contained in:
parent
6f0d16bca5
commit
62b956946f
8 changed files with 144 additions and 56 deletions
|
@ -9,7 +9,7 @@ exists($$OUT_PWD/../conf.pri) {
|
|||
include(conf.pri)
|
||||
}
|
||||
|
||||
LIBS += -framework Carbon -framework IOKit
|
||||
LIBS += -framework Carbon -framework IOKit -framework AppKit
|
||||
|
||||
QT_LANG_PATH = ../dist/qt-translations
|
||||
DIST_PATH = ../dist/mac
|
||||
|
|
|
@ -141,5 +141,6 @@ endif ()
|
|||
if (APPLE)
|
||||
find_library(IOKit_LIBRARY IOKit)
|
||||
find_library(Carbon_LIBRARY Carbon)
|
||||
target_link_libraries(qbt_base PRIVATE ${Carbon_LIBRARY} ${IOKit_LIBRARY})
|
||||
find_library(AppKit_LIBRARY AppKit)
|
||||
target_link_libraries(qbt_base PRIVATE ${Carbon_LIBRARY} ${IOKit_LIBRARY} ${AppKit_LIBRARY})
|
||||
endif (APPLE)
|
||||
|
|
|
@ -118,6 +118,11 @@ transferlistwidget.cpp
|
|||
updownratiodlg.cpp
|
||||
)
|
||||
|
||||
if (APPLE)
|
||||
list(APPEND QBT_GUI_HEADERS macutilities.h)
|
||||
list(APPEND QBT_GUI_SOURCES macutilities.mm)
|
||||
endif (APPLE)
|
||||
|
||||
if (WIN32 OR APPLE)
|
||||
list(APPEND QBT_GUI_HEADERS programupdater.h)
|
||||
list(APPEND QBT_GUI_SOURCES programupdater.cpp)
|
||||
|
|
|
@ -121,6 +121,11 @@ win32|macx {
|
|||
SOURCES += $$PWD/programupdater.cpp
|
||||
}
|
||||
|
||||
macx {
|
||||
HEADERS += $$PWD/macutilities.h
|
||||
OBJECTIVE_SOURCES += $$PWD/macutilities.mm
|
||||
}
|
||||
|
||||
FORMS += \
|
||||
$$PWD/mainwindow.ui \
|
||||
$$PWD/about.ui \
|
||||
|
|
39
src/gui/macutilities.h
Normal file
39
src/gui/macutilities.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2017 Brian Kendall <brian@briankendall.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give permission to
|
||||
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||
* and distribute the linked executables. You must obey the GNU General Public
|
||||
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify file(s), you may extend this exception to your version of the file(s),
|
||||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*/
|
||||
|
||||
#ifndef MACUTILITIES_H
|
||||
#define MACUTILITIES_H
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QSize>
|
||||
#include <objc/objc.h>
|
||||
|
||||
QPixmap pixmapForExtension(const QString &ext, const QSize &size);
|
||||
void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...));
|
||||
|
||||
#endif // MACUTILITIES_H
|
71
src/gui/macutilities.mm
Normal file
71
src/gui/macutilities.mm
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2017 Brian Kendall <brian@briankendall.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give permission to
|
||||
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||
* and distribute the linked executables. You must obey the GNU General Public
|
||||
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify file(s), you may extend this exception to your version of the file(s),
|
||||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*/
|
||||
|
||||
#include "macutilities.h"
|
||||
|
||||
#include <QtMac>
|
||||
#include <objc/message.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
QPixmap pixmapForExtension(const QString &ext, const QSize &size)
|
||||
{
|
||||
@autoreleasepool {
|
||||
NSImage *image = [[NSWorkspace sharedWorkspace] iconForFileType:ext.toNSString()];
|
||||
if (image) {
|
||||
NSRect rect = NSMakeRect(0, 0, size.width(), size.height());
|
||||
CGImageRef cgImage = [image CGImageForProposedRect:&rect context:nil hints:nil];
|
||||
return QtMac::fromCGImageRef(cgImage);
|
||||
}
|
||||
|
||||
return QPixmap();
|
||||
}
|
||||
}
|
||||
|
||||
void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...))
|
||||
{
|
||||
NSApplication *appInst = [NSApplication sharedApplication];
|
||||
|
||||
if (!appInst)
|
||||
return;
|
||||
|
||||
Class delClass = [[appInst delegate] class];
|
||||
SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
|
||||
|
||||
if (class_getInstanceMethod(delClass, shouldHandle)) {
|
||||
if (class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"))
|
||||
qDebug("Registered dock click handler (replaced original method)");
|
||||
else
|
||||
qWarning("Failed to replace method for dock click handler");
|
||||
}
|
||||
else {
|
||||
if (class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"))
|
||||
qDebug("Registered dock click handler");
|
||||
else
|
||||
qWarning("Failed to register dock click handler");
|
||||
}
|
||||
}
|
|
@ -31,8 +31,6 @@
|
|||
#include "mainwindow.h"
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include <objc/objc.h>
|
||||
#include <objc/message.h>
|
||||
#include <QtMacExtras>
|
||||
#include <QtMac>
|
||||
#endif
|
||||
|
@ -107,7 +105,11 @@
|
|||
#include "hidabletabwidget.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#if defined (Q_OS_MAC)
|
||||
#include "macutilities.h"
|
||||
#endif
|
||||
|
||||
#if defined (Q_OS_MAC)
|
||||
void qt_mac_set_dock_menu(QMenu *menu);
|
||||
#endif
|
||||
|
||||
|
@ -1294,29 +1296,9 @@ static bool dockClickHandler(id self, SEL cmd, ...)
|
|||
}
|
||||
|
||||
void MainWindow::setupDockClickHandler()
|
||||
{
|
||||
Class cls = objc_getClass("NSApplication");
|
||||
objc_object *appInst = objc_msgSend(reinterpret_cast<objc_object *>(cls), sel_registerName("sharedApplication"));
|
||||
|
||||
if (!appInst)
|
||||
return;
|
||||
|
||||
{
|
||||
dockMainWindowHandle = this;
|
||||
objc_object* delegate = objc_msgSend(appInst, sel_registerName("delegate"));
|
||||
Class delClass = reinterpret_cast<Class>(objc_msgSend(delegate, sel_registerName("class")));
|
||||
SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
|
||||
if (class_getInstanceMethod(delClass, shouldHandle)) {
|
||||
if (class_replaceMethod(delClass, shouldHandle, reinterpret_cast<IMP>(dockClickHandler), "B@:"))
|
||||
qDebug("Registered dock click handler (replaced original method)");
|
||||
else
|
||||
qWarning("Failed to replace method for dock click handler");
|
||||
}
|
||||
else {
|
||||
if (class_addMethod(delClass, shouldHandle, reinterpret_cast<IMP>(dockClickHandler), "B@:"))
|
||||
qDebug("Registered dock click handler");
|
||||
else
|
||||
qWarning("Failed to register dock click handler");
|
||||
}
|
||||
overrideDockClickHandler(dockClickHandler);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,14 +32,12 @@
|
|||
#include <QFileIconProvider>
|
||||
#include <QFileInfo>
|
||||
#include <QIcon>
|
||||
#include <QMap>
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include <Windows.h>
|
||||
#include <Shellapi.h>
|
||||
#include <QtWin>
|
||||
#elif defined(Q_OS_MAC)
|
||||
#include <objc/objc.h>
|
||||
#include <objc/message.h>
|
||||
#else
|
||||
#include <QMimeDatabase>
|
||||
#include <QMimeType>
|
||||
|
@ -52,13 +50,8 @@
|
|||
#include "torrentcontentmodelitem.h"
|
||||
#include "torrentcontentmodelfolder.h"
|
||||
#include "torrentcontentmodelfile.h"
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
struct NSImage;
|
||||
// This function is a private QtGui library export on macOS
|
||||
// See src/gui/painting/qcoregraphics_p.h for more details
|
||||
// QtMac::fromCGImageRef takes a CGImageRef and thus requires a double conversion
|
||||
QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size);
|
||||
#if defined(Q_OS_MAC)
|
||||
#include "macutilities.h"
|
||||
#endif
|
||||
|
||||
namespace
|
||||
|
@ -113,31 +106,23 @@ namespace
|
|||
{
|
||||
const QString ext = info.suffix();
|
||||
if (!ext.isEmpty()) {
|
||||
const QPixmap pixmap = pixmapForExtension(ext, QSize(32, 32));
|
||||
if (!pixmap.isNull())
|
||||
return QIcon(pixmap);
|
||||
auto cacheIter = m_iconCache.find(ext);
|
||||
|
||||
if (cacheIter != m_iconCache.end())
|
||||
return *cacheIter;
|
||||
|
||||
QIcon icon = QIcon(pixmapForExtension(ext, QSize(32, 32)));
|
||||
if (!icon.isNull()) {
|
||||
m_iconCache.insert(ext, icon);
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
|
||||
return UnifiedFileIconProvider::icon(info);
|
||||
}
|
||||
|
||||
private:
|
||||
QPixmap pixmapForExtension(const QString &ext, const QSize &size) const
|
||||
{
|
||||
QMacAutoReleasePool pool;
|
||||
objc_object *woskspaceCls = reinterpret_cast<objc_object *>(objc_getClass("NSWorkspace"));
|
||||
SEL sharedWorkspaceSel = sel_registerName("sharedWorkspace");
|
||||
SEL iconForFileTypeSel = sel_registerName("iconForFileType:");
|
||||
|
||||
objc_object *sharedWorkspace = objc_msgSend(woskspaceCls, sharedWorkspaceSel);
|
||||
if (sharedWorkspace) {
|
||||
objc_object *image = objc_msgSend(sharedWorkspace, iconForFileTypeSel, ext.toNSString());
|
||||
if (image)
|
||||
return qt_mac_toQPixmap(reinterpret_cast<NSImage *>(image), size);
|
||||
}
|
||||
|
||||
return QPixmap();
|
||||
}
|
||||
mutable QMap<QString, QIcon> m_iconCache;
|
||||
};
|
||||
#else
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue