mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-20 15:17:41 +00:00
Merge branch 'master' of https://github.com/telegramdesktop/tdesktop
This commit is contained in:
commit
89ce0ce1e2
@ -1038,6 +1038,7 @@ notifyBorder: #f1f1f1;
|
||||
notifyBorderWidth: 1px;
|
||||
notifySlowHide: 4000;
|
||||
notifyPhotoSize: 62px;
|
||||
notifyMacPhotoSize: 64px;
|
||||
notifyPhotoPos: point(9px, 9px);
|
||||
notifyClosePos: point(1px, 2px);
|
||||
notifyClose: iconedButton(btnDefIconed) {
|
||||
|
@ -314,7 +314,7 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdParama
|
||||
LPWSTR *args;
|
||||
int argsCount;
|
||||
|
||||
bool needupdate = false, autostart = false, debug = false, writeprotected = false;
|
||||
bool needupdate = false, autostart = false, debug = false, writeprotected = false, startintray = false;
|
||||
args = CommandLineToArgvW(GetCommandLine(), &argsCount);
|
||||
if (args) {
|
||||
for (int i = 1; i < argsCount; ++i) {
|
||||
@ -325,6 +325,8 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdParama
|
||||
} else if (equal(args[i], L"-debug")) {
|
||||
debug = _debug = true;
|
||||
openLog();
|
||||
} else if (equal(args[i], L"-startintray")) {
|
||||
startintray = true;
|
||||
} else if (equal(args[i], L"-writeprotected") && ++i < argsCount) {
|
||||
writeprotected = true;
|
||||
updateTo = args[i];
|
||||
@ -373,6 +375,7 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdParama
|
||||
wstring targs;
|
||||
if (autostart) targs += L" -autostart";
|
||||
if (debug) targs += L" -debug";
|
||||
if (startintray) targs += L" -startintray";
|
||||
|
||||
bool executed = false;
|
||||
if (writeprotected) { // run un-elevated
|
||||
|
@ -303,7 +303,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
writeLog("Updater started..");
|
||||
|
||||
bool needupdate = true, autostart = false, debug = false, tosettings = false;
|
||||
bool needupdate = true, autostart = false, debug = false, tosettings = false, startintray = false;
|
||||
|
||||
char *key = 0;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
@ -311,9 +311,11 @@ int main(int argc, char *argv[]) {
|
||||
needupdate = false;
|
||||
} else if (equal(argv[i], "-autostart")) {
|
||||
autostart = true;
|
||||
} else if (equal(argv[i], "-debug")) {
|
||||
debug = _debug = true;
|
||||
openLog();
|
||||
} else if (equal(argv[i], "-debug")) {
|
||||
debug = _debug = true;
|
||||
openLog();
|
||||
} else if (equal(argv[i], "-startintray")) {
|
||||
startintray = true;
|
||||
} else if (equal(argv[i], "-tosettings")) {
|
||||
tosettings = true;
|
||||
} else if (equal(argv[i], "-key") && ++i < argc) {
|
||||
@ -377,12 +379,13 @@ int main(int argc, char *argv[]) {
|
||||
char path[MaxLen] = {0};
|
||||
strcpy(path, (exeDir + "Telegram").c_str());
|
||||
|
||||
char *args[MaxArgsCount] = {0}, p_noupdate[] = "-noupdate", p_autostart[] = "-autostart", p_debug[] = "-debug", p_tosettings[] = "-tosettings", p_key[] = "-key";
|
||||
char *args[MaxArgsCount] = {0}, p_noupdate[] = "-noupdate", p_autostart[] = "-autostart", p_debug[] = "-debug", p_tosettings[] = "-tosettings", p_key[] = "-key", p_startintray[] = "-startintray";
|
||||
int argIndex = 0;
|
||||
args[argIndex++] = path;
|
||||
args[argIndex++] = p_noupdate;
|
||||
if (autostart) args[argIndex++] = p_autostart;
|
||||
if (debug) args[argIndex++] = p_debug;
|
||||
if (startintray) args[argIndex++] = p_startintray;
|
||||
if (tosettings) args[argIndex++] = p_tosettings;
|
||||
if (key) {
|
||||
args[argIndex++] = p_key;
|
||||
|
@ -78,7 +78,7 @@ int main(int argc, const char * argv[]) {
|
||||
|
||||
openLog();
|
||||
pid_t procId = 0;
|
||||
BOOL update = YES, toSettings = NO, autoStart = NO;
|
||||
BOOL update = YES, toSettings = NO, autoStart = NO, startInTray = NO;
|
||||
NSString *key = nil;
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
if ([@"-workpath" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
|
||||
@ -99,6 +99,8 @@ int main(int argc, const char * argv[]) {
|
||||
autoStart = YES;
|
||||
} else if ([@"-debug" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
|
||||
_debug = YES;
|
||||
} else if ([@"-startintray" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
|
||||
startInTray = YES;
|
||||
} else if ([@"-key" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
|
||||
if (++i < argc) key = [NSString stringWithUTF8String:argv[i]];
|
||||
}
|
||||
@ -191,6 +193,7 @@ int main(int argc, const char * argv[]) {
|
||||
NSMutableArray *args = [[NSMutableArray alloc] initWithObjects:@"-noupdate", nil];
|
||||
if (toSettings) [args addObject:@"-tosettings"];
|
||||
if (_debug) [args addObject:@"-debug"];
|
||||
if (startInTray) [args addObject:@"-startintray"];
|
||||
if (autoStart) [args addObject:@"-autostart"];
|
||||
if (key) {
|
||||
[args addObject:@"-key"];
|
||||
|
@ -843,7 +843,7 @@ namespace App {
|
||||
}
|
||||
|
||||
AudioData *feedAudio(const MTPDaudio &audio, AudioData *convert) {
|
||||
return App::audio(audio.vid.v, convert, audio.vaccess_hash.v, audio.vuser_id.v, audio.vdate.v, audio.vduration.v, audio.vdc_id.v, audio.vsize.v);
|
||||
return App::audio(audio.vid.v, convert, audio.vaccess_hash.v, audio.vuser_id.v, audio.vdate.v, qs(audio.vmime_type), audio.vduration.v, audio.vdc_id.v, audio.vsize.v);
|
||||
}
|
||||
|
||||
DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb) {
|
||||
@ -1043,7 +1043,7 @@ namespace App {
|
||||
return result;
|
||||
}
|
||||
|
||||
AudioData *audio(const AudioId &audio, AudioData *convert, const uint64 &access, int32 user, int32 date, int32 duration, int32 dc, int32 size) {
|
||||
AudioData *audio(const AudioId &audio, AudioData *convert, const uint64 &access, int32 user, int32 date, const QString &mime, int32 duration, int32 dc, int32 size) {
|
||||
if (convert) {
|
||||
if (convert->id != audio) {
|
||||
AudiosData::iterator i = audiosData.find(convert->id);
|
||||
@ -1057,6 +1057,7 @@ namespace App {
|
||||
if (!convert->user && !convert->date && (user || date)) {
|
||||
convert->user = user;
|
||||
convert->date = date;
|
||||
convert->mime = mime;
|
||||
convert->duration = duration;
|
||||
convert->dc = dc;
|
||||
convert->size = size;
|
||||
@ -1068,7 +1069,7 @@ namespace App {
|
||||
if (convert) {
|
||||
result = convert;
|
||||
} else {
|
||||
result = new AudioData(audio, access, user, date, duration, dc, size);
|
||||
result = new AudioData(audio, access, user, date, mime, duration, dc, size);
|
||||
}
|
||||
audiosData.insert(audio, result);
|
||||
} else {
|
||||
@ -1077,6 +1078,7 @@ namespace App {
|
||||
result->access = access;
|
||||
result->user = user;
|
||||
result->date = date;
|
||||
result->mime = mime;
|
||||
result->duration = duration;
|
||||
result->dc = dc;
|
||||
result->size = size;
|
||||
@ -1467,7 +1469,7 @@ namespace App {
|
||||
}
|
||||
|
||||
void playSound() {
|
||||
if (cSoundNotify()) audioPlayNotify();
|
||||
if (cSoundNotify() && !psSkipAudioNotify()) audioPlayNotify();
|
||||
}
|
||||
|
||||
void writeConfig() {
|
||||
|
@ -106,7 +106,7 @@ namespace App {
|
||||
QString peerName(const PeerData *peer, bool forDialogs = false);
|
||||
PhotoData *photo(const PhotoId &photo, PhotoData *convert = 0, const uint64 &access = 0, int32 user = 0, int32 date = 0, const ImagePtr &thumb = ImagePtr(), const ImagePtr &medium = ImagePtr(), const ImagePtr &full = ImagePtr());
|
||||
VideoData *video(const VideoId &video, VideoData *convert = 0, const uint64 &access = 0, int32 user = 0, int32 date = 0, int32 duration = 0, int32 w = 0, int32 h = 0, const ImagePtr &thumb = ImagePtr(), int32 dc = 0, int32 size = 0);
|
||||
AudioData *audio(const AudioId &audio, AudioData *convert = 0, const uint64 &access = 0, int32 user = 0, int32 date = 0, int32 duration = 0, int32 dc = 0, int32 size = 0);
|
||||
AudioData *audio(const AudioId &audio, AudioData *convert = 0, const uint64 &access = 0, int32 user = 0, int32 date = 0, const QString &mime = QString(), int32 duration = 0, int32 dc = 0, int32 size = 0);
|
||||
DocumentData *document(const DocumentId &document, DocumentData *convert = 0, const uint64 &access = 0, int32 date = 0, const QVector<MTPDocumentAttribute> &attributes = QVector<MTPDocumentAttribute>(), const QString &mime = QString(), const ImagePtr &thumb = ImagePtr(), int32 dc = 0, int32 size = 0);
|
||||
ImageLinkData *imageLink(const QString &imageLink, ImageLinkType type = InvalidImageLink, const QString &url = QString());
|
||||
void forgetMedia();
|
||||
|
@ -600,7 +600,7 @@ void VoiceMessagesLoader::onLoad(AudioData *audio) {
|
||||
|
||||
int ret = op_read_stereo(l->file, pcm, sizeof(pcm) / sizeof(*pcm));
|
||||
if (ret < 0) {
|
||||
{
|
||||
/*{
|
||||
QMutexLocker lock(&voicemsgsMutex);
|
||||
VoiceMessages *voice = audioVoice();
|
||||
if (voice) {
|
||||
@ -609,9 +609,11 @@ void VoiceMessagesLoader::onLoad(AudioData *audio) {
|
||||
m.state = VoiceMessageStopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG(("Audio Error: op_read_stereo failed, error code %1").arg(ret));
|
||||
return loadError(j);
|
||||
}*/
|
||||
LOG(("Audio Error: op_read_stereo failed, error code %1 (corrupted voice message?)").arg(ret));
|
||||
finished = true;
|
||||
break;
|
||||
// return loadError(j);
|
||||
}
|
||||
|
||||
int li = op_current_link(l->file);
|
||||
|
@ -774,6 +774,7 @@ void EmojiPan::hideStart() {
|
||||
void EmojiPan::hideFinish() {
|
||||
hide();
|
||||
_cache = QPixmap();
|
||||
_recent.setChecked(true);
|
||||
}
|
||||
|
||||
void EmojiPan::showStart() {
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "flatbutton.h"
|
||||
#include "pspecific.h"
|
||||
|
||||
#include "application.h"
|
||||
|
||||
#include "lang.h"
|
||||
|
||||
ContextMenu::ContextMenu(QWidget *parent, const style::iconedButton &st) : TWidget(0),
|
||||
@ -241,7 +243,7 @@ void ContextMenu::deleteOnHide() {
|
||||
|
||||
void ContextMenu::popup(const QPoint &p) {
|
||||
QPoint w = p - QPoint(st::dropdownPadding.left(), st::dropdownPadding.top());
|
||||
QRect r = QDesktopWidget().screenGeometry(p);
|
||||
QRect r = App::app() ? App::app()->desktop()->screenGeometry(p) : QDesktopWidget().screenGeometry(p);
|
||||
if (w.x() + width() - st::dropdownPadding.right() > r.x() + r.width()) {
|
||||
w.setX(r.x() + r.width() - width() + st::dropdownPadding.right());
|
||||
}
|
||||
|
@ -481,9 +481,11 @@ LocalImage::~LocalImage() {
|
||||
}
|
||||
|
||||
LocalImage *getImage(const QString &file, QByteArray format) {
|
||||
LocalImages::const_iterator i = localImages.constFind(file);
|
||||
QFileInfo f(file);
|
||||
QString key = qsl("//:%1//:%2//:").arg(f.size()).arg(f.lastModified().toTime_t()) + file;
|
||||
LocalImages::const_iterator i = localImages.constFind(key);
|
||||
if (i == localImages.cend()) {
|
||||
i = localImages.insert(file, new LocalImage(file, format));
|
||||
i = localImages.insert(key, new LocalImage(file, format));
|
||||
}
|
||||
return i.value();
|
||||
}
|
||||
|
@ -546,8 +546,10 @@ void AudioOpenLink::onClick(Qt::MouseButton button) const {
|
||||
AudioData *data = audio();
|
||||
if ((!data->user && !data->date) || button != Qt::LeftButton) return;
|
||||
|
||||
bool mp3 = (data->mime == QLatin1String("audio/mp3"));
|
||||
|
||||
QString already = data->already(true);
|
||||
bool play = audioVoice();
|
||||
bool play = !mp3 && audioVoice();
|
||||
if (!already.isEmpty() || (!data->data.isEmpty() && play)) {
|
||||
if (play) {
|
||||
AudioData *playing = 0;
|
||||
@ -566,7 +568,7 @@ void AudioOpenLink::onClick(Qt::MouseButton button) const {
|
||||
|
||||
if (data->status != FileReady) return;
|
||||
|
||||
QString filename = saveFileName(lang(lng_save_audio), qsl("OGG Opus Audio (*.ogg);;All files (*.*)"), qsl("audio"), qsl(".ogg"), false);
|
||||
QString filename = saveFileName(lang(lng_save_audio), mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)"), qsl("audio"), mp3 ? qsl(".mp3") : qsl(".ogg"), false);
|
||||
if (!filename.isEmpty()) {
|
||||
data->openOnSave = 1;
|
||||
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->id : 0;
|
||||
@ -586,8 +588,9 @@ void AudioSaveLink::doSave(bool forceSavingAs) const {
|
||||
}
|
||||
} else {
|
||||
QDir alreadyDir(already.isEmpty() ? QDir() : QFileInfo(already).dir());
|
||||
QString name = already.isEmpty() ? QString(".ogg") : already;
|
||||
QString filename = saveFileName(lang(lng_save_audio), qsl("OGG Opus Audio (*.ogg);;All files (*.*)"), qsl("audio"), name, forceSavingAs, alreadyDir);
|
||||
bool mp3 = (data->mime == QLatin1String("audio/mp3"));
|
||||
QString name = already.isEmpty() ? (mp3 ? qsl(".mp3") : qsl(".ogg")) : already;
|
||||
QString filename = saveFileName(lang(lng_save_audio), mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)"), qsl("audio"), name, forceSavingAs, alreadyDir);
|
||||
if (!filename.isEmpty()) {
|
||||
if (forceSavingAs) {
|
||||
data->cancel();
|
||||
@ -612,8 +615,8 @@ void AudioCancelLink::onClick(Qt::MouseButton button) const {
|
||||
data->cancel();
|
||||
}
|
||||
|
||||
AudioData::AudioData(const AudioId &id, const uint64 &access, int32 user, int32 date, int32 duration, int32 dc, int32 size) :
|
||||
id(id), access(access), user(user), date(date), duration(duration), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), openOnSaveMsgId(0), loader(0) {
|
||||
AudioData::AudioData(const AudioId &id, const uint64 &access, int32 user, int32 date, const QString &mime, int32 duration, int32 dc, int32 size) :
|
||||
id(id), access(access), user(user), date(date), mime(mime), duration(duration), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), openOnSaveMsgId(0), loader(0) {
|
||||
location = Local::readFileLocation(mediaKey(mtpc_inputAudioFileLocation, dc, id));
|
||||
}
|
||||
|
||||
@ -2607,7 +2610,8 @@ void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, i
|
||||
width = _maxw;
|
||||
}
|
||||
|
||||
if (!data->loader && data->status != FileFailed && !already && !hasdata && data->size < AudioVoiceMsgInMemory) {
|
||||
bool mp3 = (data->mime == QLatin1String("audio/mp3"));
|
||||
if (!data->loader && !mp3 && data->status != FileFailed && !already && !hasdata && data->size < AudioVoiceMsgInMemory) {
|
||||
data->save(QString());
|
||||
}
|
||||
|
||||
@ -2639,11 +2643,11 @@ void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, i
|
||||
AudioData *playing = 0;
|
||||
VoiceMessageState playingState = VoiceMessageStopped;
|
||||
int64 playingPosition = 0, playingDuration = 0;
|
||||
if (audioVoice()) {
|
||||
if (!mp3 && audioVoice()) {
|
||||
audioVoice()->currentState(&playing, &playingState, &playingPosition, &playingDuration);
|
||||
}
|
||||
QRect img;
|
||||
if (already || hasdata) {
|
||||
if (!mp3 && (already || hasdata)) {
|
||||
bool showPause = (playing == data) && (playingState == VoiceMessagePlaying || playingState == VoiceMessageResuming || playingState == VoiceMessageStarting);
|
||||
img = out ? (showPause ? st::mediaPauseOutImg : st::mediaPlayOutImg) : (showPause ? st::mediaPauseInImg : st::mediaPlayInImg);
|
||||
} else {
|
||||
@ -2667,7 +2671,7 @@ void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, i
|
||||
|
||||
style::color status(selected ? (out ? st::mediaOutSelectColor : st::mediaInSelectColor) : (out ? st::mediaOutColor : st::mediaInColor));
|
||||
p.setPen(status->p);
|
||||
if (already || hasdata) {
|
||||
if (!mp3 && (already || hasdata)) {
|
||||
if (playing == data && playingState != VoiceMessageStopped) {
|
||||
statusText = formatDurationText(playingPosition / AudioVoiceMsgFrequency) + qsl(" / ") + formatDurationText(playingDuration / AudioVoiceMsgFrequency);
|
||||
} else {
|
||||
|
@ -306,7 +306,7 @@ public:
|
||||
};
|
||||
|
||||
struct AudioData {
|
||||
AudioData(const AudioId &id, const uint64 &access = 0, int32 user = 0, int32 date = 0, int32 duration = 0, int32 dc = 0, int32 size = 0);
|
||||
AudioData(const AudioId &id, const uint64 &access = 0, int32 user = 0, int32 date = 0, const QString &mime = QString(), int32 duration = 0, int32 dc = 0, int32 size = 0);
|
||||
|
||||
void forget() {
|
||||
}
|
||||
@ -343,6 +343,7 @@ struct AudioData {
|
||||
uint64 access;
|
||||
int32 user;
|
||||
int32 date;
|
||||
QString mime;
|
||||
int32 duration;
|
||||
int32 dc;
|
||||
int32 size;
|
||||
@ -574,8 +575,8 @@ inline MediaOverviewType mediaToOverviewType(HistoryMediaType t) {
|
||||
switch (t) {
|
||||
case MediaTypePhoto: return OverviewPhotos;
|
||||
case MediaTypeVideo: return OverviewVideos;
|
||||
case MediaTypeDocument:
|
||||
case MediaTypeSticker: return OverviewDocuments;
|
||||
case MediaTypeDocument: return OverviewDocuments;
|
||||
// case MediaTypeSticker: return OverviewDocuments;
|
||||
case MediaTypeAudio: return OverviewAudios;
|
||||
}
|
||||
return OverviewCount;
|
||||
|
@ -1099,8 +1099,9 @@ void MainWidget::audioLoadProgress(mtpFileLoader *loader) {
|
||||
if (audio->loader) {
|
||||
if (audio->loader->done()) {
|
||||
audio->finish();
|
||||
bool mp3 = (audio->mime == QLatin1String("audio/mp3"));
|
||||
QString already = audio->already();
|
||||
bool play = audio->openOnSave > 0 && audioVoice();
|
||||
bool play = !mp3 && audio->openOnSave > 0 && audioVoice();
|
||||
if ((!already.isEmpty() && audio->openOnSave) || (!audio->data.isEmpty() && play)) {
|
||||
if (play) {
|
||||
AudioData *playing = 0;
|
||||
@ -2448,7 +2449,6 @@ void MainWidget::updateOnline(bool gotOtherOffline) {
|
||||
int updateIn = cOnlineUpdatePeriod();
|
||||
if (isOnline) {
|
||||
uint64 idle = psIdleTime();
|
||||
LOG(("Idle: %1").arg(idle));
|
||||
if (idle >= uint64(cOfflineIdleTimeout())) {
|
||||
isOnline = false;
|
||||
if (!_isIdle) {
|
||||
@ -2478,7 +2478,6 @@ void MainWidget::updateOnline(bool gotOtherOffline) {
|
||||
} else if (isOnline) {
|
||||
updateIn = qMin(updateIn, int(_lastSetOnline + cOnlineUpdatePeriod() - ms));
|
||||
}
|
||||
LOG(("UPDATE IN: %1").arg(updateIn));
|
||||
_onlineTimer.start(updateIn);
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ _saveMsgStarted(0), _saveMsgOpacity(0)
|
||||
|
||||
void MediaView::moveToScreen() {
|
||||
QPoint wndCenter(App::wnd()->x() + App::wnd()->width() / 2, App::wnd()->y() + App::wnd()->height() / 2);
|
||||
_avail = QDesktopWidget().screenGeometry(wndCenter);
|
||||
_avail = App::app() ? App::app()->desktop()->screenGeometry(wndCenter) : QDesktopWidget().screenGeometry(wndCenter);
|
||||
if (_avail != geometry()) {
|
||||
setGeometry(_avail);
|
||||
}
|
||||
|
@ -772,21 +772,18 @@ void PsMainWindow::psFirstShow() {
|
||||
setWindowState(Qt::WindowMaximized);
|
||||
}
|
||||
|
||||
if (cFromAutoStart()) {
|
||||
if (cStartMinimized()) {
|
||||
setWindowState(Qt::WindowMinimized);
|
||||
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
|
||||
hide();
|
||||
} else {
|
||||
show();
|
||||
}
|
||||
showShadows = false;
|
||||
if ((cFromAutoStart() && cStartMinimized()) || cStartInTray()) {
|
||||
setWindowState(Qt::WindowMinimized);
|
||||
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
|
||||
hide();
|
||||
} else {
|
||||
show();
|
||||
}
|
||||
showShadows = false;
|
||||
} else {
|
||||
show();
|
||||
}
|
||||
|
||||
posInited = true;
|
||||
}
|
||||
|
||||
@ -1324,6 +1321,14 @@ uint64 psIdleTime() {
|
||||
return getms(true) - _lastUserAction;
|
||||
}
|
||||
|
||||
bool psSkipAudioNotify() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool psSkipDesktopNotify() {
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList psInitLogs() {
|
||||
return _initLogs;
|
||||
}
|
||||
@ -1658,7 +1663,7 @@ bool _execUpdater(bool update = true) {
|
||||
QByteArray data(QFile::encodeName(cExeDir() + "Updater"));
|
||||
memcpy(path, data.constData(), data.size());
|
||||
|
||||
char *args[MaxArgsCount] = {0}, p_noupdate[] = "-noupdate", p_autostart[] = "-autostart", p_debug[] = "-debug", p_tosettings[] = "-tosettings", p_key[] = "-key", p_path[] = "-workpath";
|
||||
char *args[MaxArgsCount] = {0}, p_noupdate[] = "-noupdate", p_autostart[] = "-autostart", p_debug[] = "-debug", p_tosettings[] = "-tosettings", p_key[] = "-key", p_path[] = "-workpath", p_startintray[] = "-startintray";
|
||||
char p_datafile[MaxLen] = {0}, p_pathbuf[MaxLen] = {0};
|
||||
int argIndex = 0;
|
||||
args[argIndex++] = path;
|
||||
@ -1668,6 +1673,7 @@ bool _execUpdater(bool update = true) {
|
||||
}
|
||||
if (cFromAutoStart()) args[argIndex++] = p_autostart;
|
||||
if (cDebug()) args[argIndex++] = p_debug;
|
||||
if (cStartInTray()) args[argIndex++] = p_startintray;
|
||||
if (cDataFile() != (cTestMode() ? qsl("data_test") : qsl("data"))) {
|
||||
QByteArray dataf = QFile::encodeName(cDataFile());
|
||||
if (dataf.size() < MaxLen) {
|
||||
|
@ -169,6 +169,9 @@ private:
|
||||
void psUserActionDone();
|
||||
uint64 psIdleTime();
|
||||
|
||||
bool psSkipAudioNotify();
|
||||
bool psSkipDesktopNotify();
|
||||
|
||||
QStringList psInitLogs();
|
||||
void psClearInitLogs();
|
||||
|
||||
|
@ -290,21 +290,18 @@ void PsMainWindow::psFirstShow() {
|
||||
setWindowState(Qt::WindowMaximized);
|
||||
}
|
||||
|
||||
if (cFromAutoStart()) {
|
||||
if (cStartMinimized()) {
|
||||
setWindowState(Qt::WindowMinimized);
|
||||
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
|
||||
hide();
|
||||
} else {
|
||||
show();
|
||||
}
|
||||
showShadows = false;
|
||||
if ((cFromAutoStart() && cStartMinimized()) || cStartInTray()) {
|
||||
setWindowState(Qt::WindowMinimized);
|
||||
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
|
||||
hide();
|
||||
} else {
|
||||
show();
|
||||
}
|
||||
showShadows = false;
|
||||
} else {
|
||||
show();
|
||||
}
|
||||
|
||||
posInited = true;
|
||||
|
||||
// init global menu
|
||||
@ -480,8 +477,10 @@ void PsMainWindow::psNotifyShown(NotifyWindow *w) {
|
||||
void PsMainWindow::psPlatformNotify(HistoryItem *item) {
|
||||
QString title = (cNotifyView() <= dbinvShowName) ? item->history()->peer->name : qsl("Telegram Desktop");
|
||||
QString subtitle = (cNotifyView() <= dbinvShowName) ? item->notificationHeader() : QString();
|
||||
QPixmap pix = (cNotifyView() <= dbinvShowName) ? item->history()->peer->photo->pix(st::notifyMacPhotoSize) : QPixmap();
|
||||
QString msg = (cNotifyView() <= dbinvShowPreview) ? item->notificationText() : lang(lng_notification_preview);
|
||||
_private.showNotify(item->history()->peer->id, title, subtitle, msg, (cNotifyView() <= dbinvShowPreview));
|
||||
|
||||
_private.showNotify(item->history()->peer->id, pix, title, subtitle, msg, (cNotifyView() <= dbinvShowPreview));
|
||||
}
|
||||
|
||||
bool PsMainWindow::eventFilter(QObject *obj, QEvent *evt) {
|
||||
@ -930,6 +929,14 @@ uint64 psIdleTime() {
|
||||
return objc_idleTime(idleTime) ? idleTime : (getms(true) - _lastUserAction);
|
||||
}
|
||||
|
||||
bool psSkipAudioNotify() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool psSkipDesktopNotify() {
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList psInitLogs() {
|
||||
return _initLogs;
|
||||
}
|
||||
|
@ -197,6 +197,9 @@ private:
|
||||
void psUserActionDone();
|
||||
uint64 psIdleTime();
|
||||
|
||||
bool psSkipAudioNotify();
|
||||
bool psSkipDesktopNotify();
|
||||
|
||||
QStringList psInitLogs();
|
||||
void psClearInitLogs();
|
||||
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
|
||||
void updateDelegate();
|
||||
|
||||
void showNotify(uint64 peer, const QString &title, const QString &subtitle, const QString &msg, bool withReply);
|
||||
void showNotify(uint64 peer, const QPixmap &pix, const QString &title, const QString &subtitle, const QString &msg, bool withReply);
|
||||
void clearNotifies(uint64 peer = 0);
|
||||
|
||||
void enableShadow(WId winId);
|
||||
|
@ -148,13 +148,15 @@ public:
|
||||
|
||||
void onNotifyClick(NSUserNotification *notification) {
|
||||
NSNumber *peerObj = [[notification userInfo] objectForKey:@"peer"];
|
||||
unsigned long long peerLong = [peerObj unsignedLongLongValue];
|
||||
unsigned long long peerLong = peerObj ? [peerObj unsignedLongLongValue] : 0;
|
||||
LOG(("Received notification click with peer %1").arg(peerLong));
|
||||
wnd->notifyClicked(peerLong);
|
||||
}
|
||||
|
||||
void onNotifyReply(NSUserNotification *notification) {
|
||||
NSNumber *peerObj = [[notification userInfo] objectForKey:@"peer"];
|
||||
unsigned long long peerLong = [peerObj unsignedLongLongValue];
|
||||
unsigned long long peerLong = peerObj ? [peerObj unsignedLongLongValue] : 0;
|
||||
LOG(("Received notification reply with peer %1").arg(peerLong));
|
||||
wnd->notifyReplied(peerLong, [[[notification response] string] UTF8String]);
|
||||
}
|
||||
|
||||
@ -202,11 +204,12 @@ public:
|
||||
|
||||
- (void) userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification {
|
||||
NSNumber *instObj = [[notification userInfo] objectForKey:@"inst"];
|
||||
unsigned long long instLong = [instObj unsignedLongLongValue];
|
||||
unsigned long long instLong = instObj ? [instObj unsignedLongLongValue] : 0;
|
||||
DEBUG_LOG(("Received notification with instance %1").arg(instLong));
|
||||
if (instLong != cInstance()) { // other app instance notification
|
||||
return;
|
||||
}
|
||||
if (notification.activationType == NSUserNotificationActivationTypeReplied){
|
||||
if (notification.activationType == NSUserNotificationActivationTypeReplied) {
|
||||
wnd->data->onNotifyReply(notification);
|
||||
} else if (notification.activationType == NSUserNotificationActivationTypeContentsClicked) {
|
||||
wnd->data->onNotifyClick(notification);
|
||||
@ -255,7 +258,7 @@ void objc_showOverAll(WId winId, bool canFocus) {
|
||||
[wnd setLevel:NSPopUpMenuWindowLevel];
|
||||
if (!canFocus) {
|
||||
[wnd setStyleMask:NSUtilityWindowMask | NSNonactivatingPanelMask];
|
||||
[wnd setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces|NSWindowCollectionBehaviorFullScreenAuxiliary|NSWindowCollectionBehaviorIgnoresCycle];
|
||||
[wnd setCollectionBehavior:NSWindowCollectionBehaviorMoveToActiveSpace|NSWindowCollectionBehaviorStationary|NSWindowCollectionBehaviorFullScreenAuxiliary|NSWindowCollectionBehaviorIgnoresCycle];
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,14 +272,19 @@ void objc_activateWnd(WId winId) {
|
||||
[wnd orderFront:wnd];
|
||||
}
|
||||
|
||||
void PsMacWindowPrivate::showNotify(uint64 peer, const QString &title, const QString &subtitle, const QString &msg, bool withReply) {
|
||||
NSImage *qt_mac_create_nsimage(const QPixmap &pm);
|
||||
|
||||
void PsMacWindowPrivate::showNotify(uint64 peer, const QPixmap &pix, const QString &title, const QString &subtitle, const QString &msg, bool withReply) {
|
||||
NSUserNotification *notification = [[NSUserNotification alloc] init];
|
||||
|
||||
NSImage *img = qt_mac_create_nsimage(pix);
|
||||
|
||||
DEBUG_LOG(("Sending notification with userinfo: peer %1 and instance %2").arg(peer).arg(cInstance()));
|
||||
[notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLongLong:peer],@"peer",[NSNumber numberWithUnsignedLongLong:cInstance()],@"inst",nil]];
|
||||
|
||||
[notification setTitle:QNSString(title).s()];
|
||||
[notification setSubtitle:QNSString(subtitle).s()];
|
||||
[notification setInformativeText:QNSString(msg).s()];
|
||||
[notification setContentImage:img];
|
||||
|
||||
if (withReply) [notification setHasReplyButton:YES];
|
||||
|
||||
@ -284,7 +292,8 @@ void PsMacWindowPrivate::showNotify(uint64 peer, const QString &title, const QSt
|
||||
|
||||
NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter];
|
||||
[center deliverNotification:notification];
|
||||
|
||||
|
||||
if (img) [img release];
|
||||
[notification release];
|
||||
}
|
||||
|
||||
@ -897,6 +906,7 @@ BOOL _execUpdater(BOOL update = YES) {
|
||||
if (!update) [args addObject:@"-noupdate"];
|
||||
if (cFromAutoStart()) [args addObject:@"-autostart"];
|
||||
if (cDebug()) [args addObject:@"-debug"];
|
||||
if (cStartInTray()) [args addObject:@"-startintray"];
|
||||
if (cDataFile() != (cTestMode() ? qsl("data_test") : qsl("data"))) {
|
||||
[args addObject:@"-key"];
|
||||
[args addObject:QNSString(cDataFile()).s()];
|
||||
|
@ -29,11 +29,10 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
#include <Strsafe.h>
|
||||
#include <shlobj.h>
|
||||
#include <Windowsx.h>
|
||||
#include <WtsApi32.h>
|
||||
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
|
||||
#include <dwmapi.h>
|
||||
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define max(a, b) ((a) < (b) ? (b) : (a))
|
||||
|
||||
@ -55,16 +54,18 @@ namespace {
|
||||
QStringList _initLogs;
|
||||
|
||||
bool frameless = true;
|
||||
bool useDWM = false;
|
||||
bool useTheme = false;
|
||||
bool useOpenWith = false;
|
||||
bool useOpenAs = false;
|
||||
bool useWtsapi = false;
|
||||
bool useShellapi = false;
|
||||
bool themeInited = false;
|
||||
bool finished = true;
|
||||
int menuShown = 0, menuHidden = 0;
|
||||
int dleft = 0, dtop = 0;
|
||||
QMargins simpleMargins, margins;
|
||||
HICON bigIcon = 0, smallIcon = 0, overlayIcon = 0;
|
||||
bool sessionLoggedOff = false;
|
||||
|
||||
UINT tbCreatedMsgId = 0;
|
||||
ITaskbarList3 *tbListInterface = 0;
|
||||
@ -203,7 +204,7 @@ namespace {
|
||||
screenDC = GetDC(0);
|
||||
if (!screenDC) return false;
|
||||
|
||||
QRect avail(QDesktopWidget().availableGeometry());
|
||||
QRect avail(App::app() ? App::app()->desktop()->availableGeometry() : QDesktopWidget().availableGeometry());
|
||||
max_w = avail.width();
|
||||
if (max_w < st::wndMinWidth) max_w = st::wndMinWidth;
|
||||
max_h = avail.height();
|
||||
@ -606,15 +607,6 @@ namespace {
|
||||
|
||||
QColor _shActive(0, 0, 0), _shInactive(0, 0, 0);
|
||||
|
||||
typedef BOOL (FAR STDAPICALLTYPE *f_dwmDefWindowProc)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, _Out_ LRESULT *plResult);
|
||||
f_dwmDefWindowProc dwmDefWindowProc = 0;
|
||||
|
||||
typedef HRESULT (FAR STDAPICALLTYPE *f_dwmSetWindowAttribute)(HWND hWnd, DWORD dwAttribute, _In_ LPCVOID pvAttribute, DWORD cbAttribute);
|
||||
f_dwmSetWindowAttribute dwmSetWindowAttribute = 0;
|
||||
|
||||
typedef HRESULT (FAR STDAPICALLTYPE *f_dwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS *pMarInset);
|
||||
f_dwmExtendFrameIntoClientArea dwmExtendFrameIntoClientArea = 0;
|
||||
|
||||
typedef HRESULT (FAR STDAPICALLTYPE *f_setWindowTheme)(HWND hWnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList);
|
||||
f_setWindowTheme setWindowTheme = 0;
|
||||
|
||||
@ -627,12 +619,21 @@ namespace {
|
||||
typedef HRESULT (FAR STDAPICALLTYPE *f_shAssocEnumHandlers)(PCWSTR pszExtra, ASSOC_FILTER afFilter, IEnumAssocHandlers **ppEnumHandler);
|
||||
f_shAssocEnumHandlers shAssocEnumHandlers = 0;
|
||||
|
||||
typedef HRESULT(FAR STDAPICALLTYPE *f_shCreateItemFromParsingName)(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv);
|
||||
typedef HRESULT (FAR STDAPICALLTYPE *f_shCreateItemFromParsingName)(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv);
|
||||
f_shCreateItemFromParsingName shCreateItemFromParsingName = 0;
|
||||
|
||||
typedef HRESULT(FAR STDAPICALLTYPE *f_shLoadIndirectString)(LPCWSTR pszSource, LPWSTR pszOutBuf, UINT cchOutBuf, void **ppvReserved);
|
||||
typedef HRESULT (FAR STDAPICALLTYPE *f_shLoadIndirectString)(LPCWSTR pszSource, LPWSTR pszOutBuf, UINT cchOutBuf, void **ppvReserved);
|
||||
f_shLoadIndirectString shLoadIndirectString = 0;
|
||||
|
||||
typedef BOOL (FAR STDAPICALLTYPE *f_wtsRegisterSessionNotification)(HWND hWnd, DWORD dwFlags);
|
||||
f_wtsRegisterSessionNotification wtsRegisterSessionNotification = 0;
|
||||
|
||||
typedef BOOL (FAR STDAPICALLTYPE *f_wtsUnRegisterSessionNotification)(HWND hWnd);
|
||||
f_wtsUnRegisterSessionNotification wtsUnRegisterSessionNotification = 0;
|
||||
|
||||
typedef HRESULT (FAR STDAPICALLTYPE *f_shQueryUserNotificationState)(QUERY_USER_NOTIFICATION_STATE *pquns);
|
||||
f_shQueryUserNotificationState shQueryUserNotificationState = 0;
|
||||
|
||||
template <typename TFunction>
|
||||
bool loadFunction(HINSTANCE dll, LPCSTR name, TFunction &func) {
|
||||
if (!dll) return false;
|
||||
@ -644,20 +645,11 @@ namespace {
|
||||
class _PsInitializer {
|
||||
public:
|
||||
_PsInitializer() {
|
||||
setupDWM();
|
||||
useDWM = true;
|
||||
frameless = !useDWM;
|
||||
frameless = false;
|
||||
|
||||
setupUx();
|
||||
setupShell();
|
||||
}
|
||||
void setupDWM() {
|
||||
HINSTANCE procId = LoadLibrary(L"DWMAPI.DLL");
|
||||
|
||||
if (!loadFunction(procId, "DwmDefWindowProc", dwmDefWindowProc)) return;
|
||||
if (!loadFunction(procId, "DwmSetWindowAttribute", dwmSetWindowAttribute)) return;
|
||||
if (!loadFunction(procId, "DwmExtendFrameIntoClientArea", dwmExtendFrameIntoClientArea)) return;
|
||||
useDWM = true;
|
||||
setupWtsapi();
|
||||
}
|
||||
void setupUx() {
|
||||
HINSTANCE procId = LoadLibrary(L"UXTHEME.DLL");
|
||||
@ -669,6 +661,7 @@ namespace {
|
||||
HINSTANCE procId = LoadLibrary(L"SHELL32.DLL");
|
||||
setupOpenWith(procId);
|
||||
setupOpenAs(procId);
|
||||
setupShellapi(procId);
|
||||
}
|
||||
void setupOpenWith(HINSTANCE procId) {
|
||||
if (!loadFunction(procId, "SHAssocEnumHandlers", shAssocEnumHandlers)) return;
|
||||
@ -682,6 +675,17 @@ namespace {
|
||||
if (!loadFunction(procId, "SHOpenWithDialog", shOpenWithDialog) && !loadFunction(procId, "OpenAs_RunDLLW", openAs_RunDLL)) return;
|
||||
useOpenAs = true;
|
||||
}
|
||||
void setupWtsapi() {
|
||||
HINSTANCE procId = LoadLibrary(L"WTSAPI32.DLL");
|
||||
|
||||
if (!loadFunction(procId, "WTSRegisterSessionNotification", wtsRegisterSessionNotification)) return;
|
||||
if (!loadFunction(procId, "WTSUnRegisterSessionNotification", wtsUnRegisterSessionNotification)) return;
|
||||
useWtsapi = true;
|
||||
}
|
||||
void setupShellapi(HINSTANCE procId) {
|
||||
if (!loadFunction(procId, "SHQueryUserNotificationState", shQueryUserNotificationState)) return;
|
||||
useShellapi = true;
|
||||
}
|
||||
};
|
||||
_PsInitializer _psInitializer;
|
||||
|
||||
@ -713,6 +717,14 @@ namespace {
|
||||
}
|
||||
switch (msg) {
|
||||
|
||||
case WM_WTSSESSION_CHANGE: {
|
||||
if (wParam == WTS_SESSION_LOGOFF || wParam == WTS_SESSION_LOCK) {
|
||||
sessionLoggedOff = true;
|
||||
} else if (wParam == WTS_SESSION_LOGON || wParam == WTS_SESSION_UNLOCK) {
|
||||
sessionLoggedOff = false;
|
||||
}
|
||||
} return false;
|
||||
|
||||
case WM_DESTROY: {
|
||||
App::quit();
|
||||
} return false;
|
||||
@ -721,7 +733,6 @@ namespace {
|
||||
if (LOWORD(wParam) == WA_CLICKACTIVE) {
|
||||
App::wnd()->inactivePress(true);
|
||||
}
|
||||
Application::wnd()->psUpdateMargins();
|
||||
if (LOWORD(wParam) != WA_INACTIVE) {
|
||||
_psShadowWindows.setColor(_shActive);
|
||||
_psShadowWindows.update(_PsShadowActivate);
|
||||
@ -734,33 +745,38 @@ namespace {
|
||||
|
||||
case WM_NCPAINT: if (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8) return false; *result = 0; return true;
|
||||
|
||||
case WM_NCCALCSIZE: if (!useDWM) return false; {
|
||||
if (wParam == TRUE) {
|
||||
case WM_NCCALCSIZE: {
|
||||
WINDOWPLACEMENT wp;
|
||||
wp.length = sizeof(WINDOWPLACEMENT);
|
||||
if (GetWindowPlacement(hWnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED) {
|
||||
LPNCCALCSIZE_PARAMS params = (LPNCCALCSIZE_PARAMS)lParam;
|
||||
params->rgrc[0].left += margins.left() - simpleMargins.left();
|
||||
params->rgrc[0].top += margins.top() - simpleMargins.top();
|
||||
params->rgrc[0].right -= margins.right() - simpleMargins.right();
|
||||
params->rgrc[0].bottom -= margins.bottom() - simpleMargins.bottom();
|
||||
} else if (wParam == FALSE) {
|
||||
LPRECT rect = (LPRECT)lParam;
|
||||
|
||||
rect->left += margins.left() - simpleMargins.left();
|
||||
rect->top += margins.top() - simpleMargins.top();
|
||||
rect->right += margins.right() - simpleMargins.right();
|
||||
rect->bottom += margins.bottom() - simpleMargins.bottom();
|
||||
LPRECT r = (wParam == TRUE) ? ¶ms->rgrc[0] : (LPRECT)lParam;
|
||||
HMONITOR hMonitor = MonitorFromPoint({ (r->left + r->right) / 2, (r->top + r->bottom) / 2 }, MONITOR_DEFAULTTONEAREST);
|
||||
if (hMonitor) {
|
||||
MONITORINFO mi;
|
||||
mi.cbSize = sizeof(mi);
|
||||
if (GetMonitorInfo(hMonitor, &mi)) {
|
||||
*r = mi.rcWork;
|
||||
}
|
||||
}
|
||||
}
|
||||
*result = 0;
|
||||
} return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
case WM_NCACTIVATE: {
|
||||
Application::wnd()->psUpdateMargins();
|
||||
*result = LRESULT(TRUE);
|
||||
Application::wnd()->repaint();
|
||||
*result = DefWindowProc(hWnd, msg, wParam, -1);
|
||||
} return true;
|
||||
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
case WM_WINDOWPOSCHANGED: {
|
||||
_psShadowWindows.update(_PsShadowMoved | _PsShadowResized, (WINDOWPOS*)lParam);
|
||||
WINDOWPLACEMENT wp;
|
||||
wp.length = sizeof(WINDOWPLACEMENT);
|
||||
if (GetWindowPlacement(hWnd, &wp) && (wp.showCmd == SW_SHOWMAXIMIZED || wp.showCmd == SW_SHOWMINIMIZED)) {
|
||||
_psShadowWindows.update(_PsShadowHidden);
|
||||
} else {
|
||||
_psShadowWindows.update(_PsShadowMoved | _PsShadowResized, (WINDOWPOS*)lParam);
|
||||
}
|
||||
} return false;
|
||||
|
||||
case WM_SIZE: {
|
||||
@ -777,6 +793,7 @@ namespace {
|
||||
} else {
|
||||
App::wnd()->psUpdatedPosition();
|
||||
}
|
||||
App::wnd()->psUpdateMargins();
|
||||
int changes = (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXIMIZED) ? _PsShadowHidden : (_PsShadowResized | _PsShadowShown);
|
||||
_psShadowWindows.update(changes);
|
||||
}
|
||||
@ -964,6 +981,7 @@ void PsMainWindow::psUpdateWorkmode() {
|
||||
|
||||
HICON qt_pixmapToWinHICON(const QPixmap &);
|
||||
HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &, int hbitmapFormat);
|
||||
|
||||
static HICON _qt_createHIcon(const QIcon &icon, int xSize, int ySize) {
|
||||
if (!icon.isNull()) {
|
||||
const QPixmap pm = icon.pixmap(icon.actualSize(QSize(xSize, ySize)));
|
||||
@ -1003,6 +1021,7 @@ void PsMainWindow::psUpdateCounter() {
|
||||
description.toWCharArray(descriptionArr);
|
||||
tbListInterface->SetOverlayIcon(ps_hWnd, ps_iconOverlay, descriptionArr);
|
||||
}
|
||||
SetWindowPos(ps_hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
void PsMainWindow::psUpdateDelegate() {
|
||||
@ -1039,7 +1058,7 @@ void PsMainWindow::psInitSize() {
|
||||
pos.w = st::wndDefWidth;
|
||||
pos.h = st::wndDefHeight;
|
||||
}
|
||||
QRect avail(QDesktopWidget().availableGeometry());
|
||||
QRect avail(App::app() ? App::app()->desktop()->availableGeometry() : QDesktopWidget().availableGeometry());
|
||||
bool maximized = false;
|
||||
QRect geom(avail.x() + (avail.width() - st::wndDefWidth) / 2, avail.y() + (avail.height() - st::wndDefHeight) / 2, st::wndDefWidth, st::wndDefHeight);
|
||||
if (pos.w && pos.h) {
|
||||
@ -1072,6 +1091,8 @@ void PsMainWindow::psInitFrameless() {
|
||||
|
||||
if (!ps_hWnd) return;
|
||||
|
||||
if (useWtsapi) wtsRegisterSessionNotification(ps_hWnd, NOTIFY_FOR_THIS_SESSION);
|
||||
|
||||
if (frameless) {
|
||||
setWindowFlags(Qt::FramelessWindowHint);
|
||||
}
|
||||
@ -1138,21 +1159,18 @@ void PsMainWindow::psFirstShow() {
|
||||
setWindowState(Qt::WindowMaximized);
|
||||
}
|
||||
|
||||
if (cFromAutoStart()) {
|
||||
if (cStartMinimized()) {
|
||||
setWindowState(Qt::WindowMinimized);
|
||||
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
|
||||
hide();
|
||||
} else {
|
||||
show();
|
||||
}
|
||||
showShadows = false;
|
||||
if ((cFromAutoStart() && cStartMinimized()) || cStartInTray()) {
|
||||
setWindowState(Qt::WindowMinimized);
|
||||
if (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray) {
|
||||
hide();
|
||||
} else {
|
||||
show();
|
||||
}
|
||||
showShadows = false;
|
||||
} else {
|
||||
show();
|
||||
}
|
||||
|
||||
posInited = true;
|
||||
if (showShadows) {
|
||||
_psShadowWindows.update(_PsShadowMoved | _PsShadowResized | _PsShadowShown);
|
||||
@ -1160,7 +1178,7 @@ void PsMainWindow::psFirstShow() {
|
||||
}
|
||||
|
||||
bool PsMainWindow::psHandleTitle() {
|
||||
return useDWM;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PsMainWindow::psInitSysMenu() {
|
||||
@ -1213,7 +1231,7 @@ void PsMainWindow::psUpdateSysMenu(Qt::WindowState state) {
|
||||
}
|
||||
|
||||
void PsMainWindow::psUpdateMargins() {
|
||||
if (!useDWM) return;
|
||||
if (!ps_hWnd) return;
|
||||
|
||||
RECT r, a;
|
||||
|
||||
@ -1222,7 +1240,7 @@ void PsMainWindow::psUpdateMargins() {
|
||||
|
||||
LONG style = GetWindowLong(ps_hWnd, GWL_STYLE), styleEx = GetWindowLong(ps_hWnd, GWL_EXSTYLE);
|
||||
AdjustWindowRectEx(&a, style, false, styleEx);
|
||||
simpleMargins = QMargins(a.left - r.left, a.top - r.top, r.right - a.right, r.bottom - a.bottom);
|
||||
QMargins margins = QMargins(a.left - r.left, a.top - r.top, r.right - a.right, r.bottom - a.bottom);
|
||||
if (style & WS_MAXIMIZE) {
|
||||
RECT w, m;
|
||||
GetWindowRect(ps_hWnd, &w);
|
||||
@ -1239,23 +1257,22 @@ void PsMainWindow::psUpdateMargins() {
|
||||
dleft = w.left - m.left;
|
||||
dtop = w.top - m.top;
|
||||
|
||||
margins.setLeft(simpleMargins.left() - w.left + m.left);
|
||||
margins.setRight(simpleMargins.right() - m.right + w.right);
|
||||
margins.setBottom(simpleMargins.bottom() - m.bottom + w.bottom);
|
||||
margins.setTop(simpleMargins.top() - w.top + m.top);
|
||||
margins.setLeft(margins.left() - w.left + m.left);
|
||||
margins.setRight(margins.right() - m.right + w.right);
|
||||
margins.setBottom(margins.bottom() - m.bottom + w.bottom);
|
||||
margins.setTop(margins.top() - w.top + m.top);
|
||||
} else {
|
||||
margins = simpleMargins;
|
||||
dleft = dtop = 0;
|
||||
}
|
||||
|
||||
QPlatformNativeInterface *i = QGuiApplication::platformNativeInterface();
|
||||
i->setWindowProperty(windowHandle()->handle(), "WindowsCustomMargins", QVariant::fromValue<QMargins>(margins));
|
||||
i->setWindowProperty(windowHandle()->handle(), qsl("WindowsCustomMargins"), QVariant::fromValue<QMargins>(margins));
|
||||
if (!themeInited) {
|
||||
themeInited = true;
|
||||
if (useTheme) {
|
||||
if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS8) {
|
||||
setWindowTheme(ps_hWnd, L" ", L" ");
|
||||
QApplication::setStyle(QStyleFactory::create("Windows"));
|
||||
QApplication::setStyle(QStyleFactory::create(qsl("Windows")));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1297,6 +1314,13 @@ void PsMainWindow::psDestroyIcons() {
|
||||
}
|
||||
|
||||
PsMainWindow::~PsMainWindow() {
|
||||
if (useWtsapi) {
|
||||
QPlatformNativeInterface *i = QGuiApplication::platformNativeInterface();
|
||||
if (HWND hWnd = static_cast<HWND>(i->nativeResourceForWindow(QByteArrayLiteral("handle"), windowHandle()))) {
|
||||
wtsUnRegisterSessionNotification(hWnd);
|
||||
}
|
||||
}
|
||||
|
||||
finished = true;
|
||||
if (ps_menu) DestroyMenu(ps_menu);
|
||||
psDestroyIcons();
|
||||
@ -1742,6 +1766,7 @@ namespace {
|
||||
|
||||
void psUserActionDone() {
|
||||
_lastUserAction = getms(true);
|
||||
if (sessionLoggedOff) sessionLoggedOff = false;
|
||||
}
|
||||
|
||||
uint64 psIdleTime() {
|
||||
@ -1750,6 +1775,22 @@ uint64 psIdleTime() {
|
||||
return GetLastInputInfo(&lii) ? (GetTickCount() - lii.dwTime) : (getms(true) - _lastUserAction);
|
||||
}
|
||||
|
||||
bool psSkipAudioNotify() {
|
||||
QUERY_USER_NOTIFICATION_STATE state;
|
||||
if (useShellapi && SUCCEEDED(shQueryUserNotificationState(&state))) {
|
||||
if (state == QUNS_NOT_PRESENT || state == QUNS_PRESENTATION_MODE) return true;
|
||||
}
|
||||
return sessionLoggedOff;
|
||||
}
|
||||
|
||||
bool psSkipDesktopNotify() {
|
||||
QUERY_USER_NOTIFICATION_STATE state;
|
||||
if (useShellapi && SUCCEEDED(shQueryUserNotificationState(&state))) {
|
||||
if (state == QUNS_PRESENTATION_MODE || state == QUNS_RUNNING_D3D_FULL_SCREEN || state == QUNS_BUSY) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList psInitLogs() {
|
||||
return _initLogs;
|
||||
}
|
||||
@ -2400,6 +2441,7 @@ void psExecUpdater() {
|
||||
QString targs = qsl("-update");
|
||||
if (cFromAutoStart()) targs += qsl(" -autostart");
|
||||
if (cDebug()) targs += qsl(" -debug");
|
||||
if (cStartInTray()) targs += qsl(" -startintray");
|
||||
if (cWriteProtected()) targs += qsl(" -writeprotected \"") + cExeDir() + '"';
|
||||
|
||||
QString updaterPath = cWriteProtected() ? (cWorkingDir() + qsl("tupdates/ready/Updater.exe")) : (cExeDir() + qsl("Updater.exe"));
|
||||
@ -2420,6 +2462,7 @@ void psExecTelegram() {
|
||||
if (cRestartingToSettings()) targs += qsl(" -tosettings");
|
||||
if (cFromAutoStart()) targs += qsl(" -autostart");
|
||||
if (cDebug()) targs += qsl(" -debug");
|
||||
if (cStartInTray()) targs += qsl(" -startintray");
|
||||
if (cDataFile() != (cTestMode() ? qsl("data_test") : qsl("data"))) targs += qsl(" -key \"") + cDataFile() + '"';
|
||||
|
||||
QString telegram(QDir::toNativeSeparators(cExeDir() + QString::fromWCharArray(AppFile) + qsl(".exe"))), wdir(QDir::toNativeSeparators(cWorkingDir()));
|
||||
|
@ -170,6 +170,9 @@ private:
|
||||
void psUserActionDone();
|
||||
uint64 psIdleTime();
|
||||
|
||||
bool psSkipAudioNotify();
|
||||
bool psSkipDesktopNotify();
|
||||
|
||||
QStringList psInitLogs();
|
||||
void psClearInitLogs();
|
||||
|
||||
|
@ -37,6 +37,7 @@ bool gSoundNotify = true;
|
||||
bool gDesktopNotify = true;
|
||||
DBINotifyView gNotifyView = dbinvShowPreview;
|
||||
bool gStartMinimized = false;
|
||||
bool gStartInTray = false;
|
||||
bool gAutoStart = false;
|
||||
bool gSendToMenu = false;
|
||||
bool gAutoUpdate = true;
|
||||
@ -129,7 +130,7 @@ int gOtherOnline = 0;
|
||||
|
||||
void settingsParseArgs(int argc, char *argv[]) {
|
||||
if (cPlatform() == dbipMac) {
|
||||
gCustomNotifies = false;
|
||||
gCustomNotifies = (QSysInfo::macVersion() < QSysInfo::MV_10_8);
|
||||
} else {
|
||||
gCustomNotifies = true;
|
||||
}
|
||||
@ -151,6 +152,8 @@ void settingsParseArgs(int argc, char *argv[]) {
|
||||
gNoStartUpdate = true;
|
||||
} else if (string("-tosettings") == argv[i]) {
|
||||
gStartToSettings = true;
|
||||
} else if (string("-startintray") == argv[i]) {
|
||||
gStartInTray = true;
|
||||
} else if (string("-sendpath") == argv[i] && i + 1 < argc) {
|
||||
for (++i; i < argc; ++i) {
|
||||
gSendPaths.push_back(QString::fromLocal8Bit(argv[i]));
|
||||
@ -169,7 +172,7 @@ void settingsParseArgs(int argc, char *argv[]) {
|
||||
const RecentEmojiPack &cGetRecentEmojis() {
|
||||
if (cRecentEmojis().isEmpty()) {
|
||||
RecentEmojiPack r;
|
||||
if (false && !cRecentEmojisPreload().isEmpty()) {
|
||||
if (!cRecentEmojisPreload().isEmpty()) {
|
||||
RecentEmojiPreload p(cRecentEmojisPreload());
|
||||
cSetRecentEmojisPreload(RecentEmojiPreload());
|
||||
r.reserve(p.size());
|
||||
|
@ -46,6 +46,7 @@ DeclareSetting(QString, LoggedPhoneNumber);
|
||||
DeclareReadSetting(uint32, ConnectionsInSession);
|
||||
DeclareSetting(bool, AutoStart);
|
||||
DeclareSetting(bool, StartMinimized);
|
||||
DeclareSetting(bool, StartInTray);
|
||||
DeclareSetting(bool, SendToMenu);
|
||||
DeclareReadSetting(bool, FromAutoStart);
|
||||
DeclareSetting(QString, WorkingDir);
|
||||
|
@ -302,7 +302,7 @@ void TitleWidget::showUpdateBtn() {
|
||||
_update.hide();
|
||||
if (cPlatform() == dbipWindows) {
|
||||
_minimize.show();
|
||||
maximizedChanged(wnd->windowState().testFlag(Qt::WindowMaximized), true);
|
||||
maximizedChanged(lastMaximized, true);
|
||||
_close.show();
|
||||
}
|
||||
anim::stop(this);
|
||||
|
@ -384,7 +384,6 @@ void Window::stateChanged(Qt::WindowState state) {
|
||||
updateIsActive((state == Qt::WindowMinimized) ? cOfflineBlurTimeout() : cOnlineFocusTimeout());
|
||||
|
||||
psUpdateSysMenu(state);
|
||||
psUpdateMargins();
|
||||
if (state == Qt::WindowMinimized && cWorkMode() == dbiwmTrayOnly) {
|
||||
App::wnd()->minimizeToTray();
|
||||
}
|
||||
@ -1133,7 +1132,7 @@ void Window::notifySchedule(History *history, MsgId msgId) {
|
||||
|
||||
uint64 when = getms(true) + delay;
|
||||
notifyWhenAlerts[history].insert(when, NullType());
|
||||
if (cDesktopNotify()) {
|
||||
if (cDesktopNotify() && !psSkipDesktopNotify()) {
|
||||
NotifyWhenMaps::iterator i = notifyWhenMaps.find(history);
|
||||
if (i == notifyWhenMaps.end()) {
|
||||
i = notifyWhenMaps.insert(history, NotifyWhenMap());
|
||||
@ -1256,7 +1255,7 @@ void Window::notifyShowNext(NotifyWindow *remove) {
|
||||
--count;
|
||||
}
|
||||
}
|
||||
if (count <= 0 || !cDesktopNotify()) {
|
||||
if (count <= 0 || notifyWaiters.isEmpty() || !cDesktopNotify() || psSkipDesktopNotify()) {
|
||||
if (nextAlert) {
|
||||
notifyWaitTimer.start(nextAlert - ms);
|
||||
}
|
||||
|
@ -1780,6 +1780,7 @@
|
||||
<None Include="SourceFiles\langs\lang_de.strings" />
|
||||
<None Include="SourceFiles\langs\lang_es.strings" />
|
||||
<None Include="SourceFiles\langs\lang_it.strings" />
|
||||
<None Include="SourceFiles\langs\lang_ko.strings" />
|
||||
<None Include="SourceFiles\langs\lang_nl.strings" />
|
||||
<None Include="SourceFiles\langs\lang_pt_BR.strings" />
|
||||
</ItemGroup>
|
||||
|
@ -1060,5 +1060,8 @@
|
||||
<None Include="SourceFiles\langs\lang_pt_BR.strings">
|
||||
<Filter>langs</Filter>
|
||||
</None>
|
||||
<None Include="SourceFiles\langs\lang_ko.strings">
|
||||
<Filter>langs</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user