New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed mac specific compiler errors and cleaned up Objective C code. Closes #7252 #7253
Fixed mac specific compiler errors and cleaned up Objective C code. Closes #7252 #7253
Conversation
@vit9696 you might want to see this. @briankendall I see that the new code is "different" syntactically. If yours objective-c++ what was the previous? It seemed more C/C++. |
@@ -0,0 +1,13 @@ | |||
#ifndef MACUTILITIES_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to put standard project header in your files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made this change. Please let me know if I got the header correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should specify the email after your name. You don't want to do it because of some reasons?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed Mike used his github name and went with that but I can change it to my email.
src/gui/macutilities.h
Outdated
#ifndef MACUTILITIES_H | ||
#define MACUTILITIES_H | ||
|
||
#ifdef Q_OS_MAC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should use this ifdef
in that place where you include this header, not here.
src/gui/macutilities.h
Outdated
void overrideDockClickHandler(bool (*dockClickHandler)(id, SEL, ...)); | ||
#endif | ||
|
||
#endif // MACUTILITIES_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that something wrong is here... Do you have linebreak at the end of file?
src/gui/macutilities.mm
Outdated
#import <Cocoa/Cocoa.h> | ||
#include <QtMac> | ||
#include <objc/message.h> | ||
#include "macutilities.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix includes order. See Coding Guidelines.
Hello, I will reply here on both the issue (#7252) and the pull request.
Be that microoptimisation or not, this code is being invoked pretty frequently, and from what I remember from the logs, not just once per appearance, but way more often for some reason. On dual-gpu macs or macs with just discrete gpus I may well imagine slowdowns due to constant ram <--> vram uploading. From my own side, I do not see a reason to use 5.7 or even 5.8 on 10.12.x. They are not even supportedby Qt itself, and if one wants 10.9.x support, there is 5.8, which has the function in the correct place. (By the way, @sledgehammer999, I am starting to wonder, whether it could be a good idea to provide the official binaries linked to 5.8, so that they work on 10.9, or even 5.7 to get 10.8 support back?)
In any case, I am not too against this code since it already is written and this way is easier to maintain. But one should at least visually check the performance on torrents with thousands of files. I guess Qt does not do things rightly in most of the places anyway, so it may well be "ok". |
You're right, it is called a lot. I think the appropriate thing to do if we're being performance minded is to cache the icons. Anyone have any objections to changing
It does involve some tomfoolery with modifying a member variable in a
|
The Windows one seems to be suffering from the same problem.
private:
mutable QMap<QString, QIcon> iconCache; |
@briankendall, actually given the small size of the icons caching is likely the right way. Other than mutable I would suggest you avoid double search in all the places:
The above suggestions are minor code cleaning stuff, but there is an actual bug. |
677b718
to
040909d
Compare
src/gui/torrentcontentmodel.cpp
Outdated
return cacheEntry.value(); | ||
|
||
QIcon icon = QIcon(pixmapForExtension(ext, QSize(32, 32))); | ||
if (!icon.isNull()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
braces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or return *m_iconCache.insert(ext, icon);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Braces is correct. The coding style I'm used to has braces being used on every if statement even when they're one line... mainly so I don't have to worry about making silly mistakes like I just did.
040909d
to
810fe91
Compare
This looks like a change introduced in 5.8, surprisingly nothing in the docs says about it. In 5.8 and above NSString is defined as class in c++ code and as as an objective C class in objc/objc++ code. Thus QString header has no ifdefs against defining toNSString, and buildbots eat this code without issues. #if defined(Q_OS_DARWIN) || defined(Q_QDOC)
static QString fromCFString(CFStringRef string);
CFStringRef toCFString() const Q_DECL_CF_RETURNS_RETAINED;
static QString fromNSString(const NSString *string);
NSString *toNSString() const Q_DECL_NS_RETURNS_AUTORELEASED;
#endif Yet in 5.7 there indeed was a check for objc, which is rather unfortunate. As for pull-request changes I marked one in code, the rest looks more or less good, except maybe some style issues qBittorrent devs find more often than anything :D. |
src/gui/mainwindow.cpp
Outdated
@@ -106,6 +104,9 @@ | |||
#include "executionlog.h" | |||
#include "hidabletabwidget.h" | |||
#include "ui_mainwindow.h" | |||
#if defined (Q_OS_MAC) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls add an empty line above this.
src/gui/torrentcontentmodel.cpp
Outdated
auto cacheEntry = m_iconCache.find(ext); | ||
|
||
if (cacheEntry != m_iconCache.end()) | ||
return cacheEntry.value(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
personal opinion:
- I would name it
cacheIter
or something like that.cacheEntry
sounds like its type isQIcon
. return *cacheIter;
, I'm so used to usingoperator*
to dereference an iterator.
810fe91
to
f5152d7
Compare
src/gui/torrentcontentmodel.cpp
Outdated
} | ||
|
||
return UnifiedFileIconProvider::icon(info); | ||
} | ||
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've inserted some redundant spaces in this line. Remove it, please.
f5152d7
to
da285a7
Compare
QIcon icon = QIcon(pixmapForExtension(ext, QSize(32, 32))); | ||
if (!icon.isNull()) { | ||
m_iconCache.insert(ext, icon); | ||
return icon; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, one last thing, move return
outside/below the if(){}
so that the function will always return something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we want to avoid returning a null icon. If it's null, it'll exit the if block and hit return UnifiedFileIconProvider::icon(info);
. So that way it falls back on the behavior of UnifiedFileIconProvider
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
damn, I missed the return
below, so nevermind this.
src/gui/CMakeLists.txt
Outdated
@@ -118,6 +118,10 @@ transferlistwidget.cpp | |||
updownratiodlg.cpp | |||
) | |||
|
|||
if (APPLE) | |||
list(APPEND QBT_GUI_SOURCES macutilities.mm) | |||
endif (APPLE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to add macutilities.h
to QBT_GUI_HEADERS as well, since the code below does it at least.
Ugh, don't tell me github did not send it right away :/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I forgot to add that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
2bd9051
to
b13a355
Compare
src/gui/gui.pri
Outdated
@@ -121,6 +121,10 @@ win32|macx { | |||
SOURCES += $$PWD/programupdater.cpp | |||
} | |||
|
|||
macx { | |||
OBJECTIVE_SOURCES += $$PWD/macutilities.mm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't "macutilities.h" be in project too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, I forgot to add it.
About icon-caching: Minor side-effect is that we won't pickup any changes made in the system after first time querying each file extension. eg new icon registered. About the NSImage to QPixmap conversion: Should we just copy the implementation of
Hmm, maybe that is a good idea. Both 10.9 and 10.12 are supported this way. |
const QPixmap pixmap = pixmapForExtension(ext, QSize(32, 32)); | ||
if (!pixmap.isNull()) | ||
return QIcon(pixmap); | ||
auto cacheIter = m_iconCache.find(ext); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should come in a separate commit.
Or since it is out-of-scope for this PR, you can leave it unimplemented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not in a position to build or test in Windows right now so I'd prefer to leave it for a separate PR.
@sledgehammer999 I'm not too worried about using out-of-date icons, because a) they rarely change for a particular file type, and b) the cache only lasts as long as the torrent that's being displayed in the GUI since it's a member of Re: Re: |
b13a355
to
cf95a95
Compare
As I said it is a minor issue. I don't think it warrants the coplexity of timestamping.
As you said performance wise it probably won't be measurable, but it is sweet that the cache is application wide and different torrents can share the icons for the same file extension.
You're right, the cache pretty much makes this moot. |
src/gui/macutilities.mm
Outdated
@autoreleasepool { | ||
NSImage *image = [[NSWorkspace sharedWorkspace] iconForFileType:ext.toNSString()]; | ||
if (image) { | ||
CGImageRef cgImage = [image CGImageForProposedRect:nil context:nil hints:nil]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better to do this instead?
NSRect rect = NSMakeRect(0, 0, size.width(), size.height());
CGImageRef cgImage = [image CGImageForProposedRect:&rect context:nil hints:nil];
And not scale it below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That does make sense. I had misunderstood what the purpose of the first parameter of CGImageForProposedRect
was for.
src/gui/mainwindow.cpp
Outdated
@@ -107,6 +105,10 @@ | |||
#include "hidabletabwidget.h" | |||
#include "ui_mainwindow.h" | |||
|
|||
#if defined (Q_OS_MAC) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's keep it the same in the same file
#ifdef Q_OS_MAC
src/gui/torrentcontentmodel.cpp
Outdated
// 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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused. In torrentcontentmodel.cpp it's consistently written as #if defined(...)
in each instance, including ones that were already there. Do you want me to change it to #ifdef
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer #ifdef Q_OS_MAC
as it was like that before your edit.
The rest of the file is a bit inconsistent.
In my opinion this PR should not use QPixmapCache, although it might be an idea for the future development. The main reason against is what one should cache, what limits should there be, how much of QPixmapCachw should file icons use. This is more an application-wide decision than a local platform-specific change. There already are tons of issues with icons, especially on mac. And I personally hope #6698 gets merged soon, even if without many changes, so that some sort of icon categorisation (or better to say tagging) could later appear with the fixes to ugly icon highlightion that should not happen on mac. And based on that some icon categories could be cacheable. Therefore it is better not to make way too much mess and redo things many times. |
OK, unless someone of the devs agrees with me leave the cache as you have implemented it. |
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.
cf95a95
to
62b9569
Compare
src/gui/mainwindow.cpp
Outdated
@@ -107,7 +105,11 @@ | |||
#include "hidabletabwidget.h" | |||
#include "ui_mainwindow.h" | |||
|
|||
#ifdef Q_OS_MAC | |||
#if defined (Q_OS_MAC) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change it to #ifdef Q_OS_MAC
as it was previously.
src/gui/mainwindow.cpp
Outdated
#include "macutilities.h" | ||
#endif | ||
|
||
#if defined (Q_OS_MAC) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
Unfortunately I’m out of town until the 23rd so I won’t be able to make these changes until then. |
@sledgehammer999 maybe merge this as is, and then push my commit 56366b0 on top of it? Other than those ifdefs, which I fixed myself, there is nothing wrong here, and without macutilities.mm merged it is pretty problematic to work on anything else. The reason is that you might want to release 3.4.0 reasonably soon, and currently notifications are entirely broken in macOS (have never known that they worked before, so could not have checked). I suppose it is a pretty critical regression, and one must fix it before 3.4.0 lands. |
@vit9696 I was planning to do something similar. But where the hell is that commit you are referencing? On which branch? It points to a commit from this repo but I can't find it locally or which PR introduced it. |
@sledgehammer999 I am afraid something is up to shithub to mess it up :/ |
@sledgehammer999, you can fetch this branch, squash its commits and add some fixups yourself and then force push it here (to this PR author repo). |
It worked!!! @briankendall thx. |
@vit9696 can you open a PR for your notifications fix? |
Yes, done #7281. |
Implements changes suggested in #7252
I removed the use of a private Qt function that was causing link errors, added a new file
src/gui/macutilities.mm
so that there's a place to write Objective-C functions that can be used from C++, and converted the two places where the Objective-C runtime was being used in C++ into real Objective C and moved it into this new file.