diff --git a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.de.qm b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.de.qm index 1332826..792b49a 100644 Binary files a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.de.qm and b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.de.qm differ diff --git a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.de.ts b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.de.ts index 4bc3e64..a05eaae 100644 --- a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.de.ts +++ b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.de.ts @@ -241,7 +241,7 @@ Symbol umkehren - + Number properties Nummereigenschaften @@ -250,67 +250,67 @@ Anzahl neuer Nachrichten anzeigen - + Number color Nummerfarbe - + Number size Nummergröße - + Alignment Nummernausrichtung - + Top left Oben links - + Top centre Oben in der Mitte - + Top right Oben rechts - + Middle left Mitte links - + Middle centre Mittleres Zentrum - + Middle right Mitte rechts - + Bottom left Unten links - + Bottom centre Unten in der Mitte - + Bottom right Unten rechts - + Margins (left, top, right, bottom): Ränder (links, oben, rechts, unten): @@ -350,79 +350,89 @@ Neue Nachrichten - + New indicator Neu Indikator - + Icon round Symbol rund - + Icon star Symbol Stern - + Shade Schattierung - + + Special options + Sonderoptionen + + + + API count method + API-Zählmethode + + + Apps Anwendungen - + Close application Stopanwendung - - + + Browse... Durchsuche... - - + + Arguments: Argumente: - + Start application Startanwendung - + Mail Nachrichten - + Use the preferences dialog in Thunderbird to select the accounts and folders Verwenden Sie den Einstellungsdialog in Thunderbird, um die Konten und Ordner auszuwählen - + Debug Debug - + Display debug window Debug-Fenster anzeigen - + Save Speichern - + Cancel Annullieren @@ -433,20 +443,20 @@ Hauptfenster minimieren - - + + Open Image Bild öffnen - - + + Image Files (*.png *.jpg *.bmp) Bilddateien (*.png *.jpg *.bmp) - - + + Select application Anwendung auswählen @@ -454,27 +464,27 @@ SysTrayX - + &Show/Hide &Anzeigen/Verbergen - + &Preferences &Einstellungen - + &About &Über - + &Quit &Beenden - + Close Schließen diff --git a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.el.qm b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.el.qm index 1d7c0f5..d18570c 100644 Binary files a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.el.qm and b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.el.qm differ diff --git a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.el.ts b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.el.ts index 600da5b..38eef01 100644 --- a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.el.ts +++ b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.el.ts @@ -241,7 +241,7 @@ Αντιστρέψτε εικονίδιο - + Number properties Ιδιότητες αριθμών @@ -250,67 +250,67 @@ Προβολή μετρητή μη-αναγνωσμένης αλληλογραφίας - + Number color Χρώμα μετρητή - + Number size Μέγεθος μετρητή - + Alignment Ευθυγραμμία - + Top left Κορυφαίο αριστερά - + Top centre Κορυφαίο κέντρο - + Top right Κορυφαίο δεξιά - + Middle left Μέση αριστερά - + Middle centre Μεσαίο κέντρο - + Middle right Μέση δεξιά - + Bottom left Κάτω αριστερά - + Bottom centre Κάτω κέντρο - + Bottom right Κάτω δεξιά - + Margins (left, top, right, bottom): Περιθώρια (αριστερά, Κορυφαίο, δεξιά, Κάτω): @@ -350,59 +350,69 @@ Νέα - + New indicator Νέος δείκτης - + Icon round Στρογγυλό εικονίδιο - + Icon star Αστέρι εικονίδιο - + Shade Απόχρωση - + + Special options + Ειδικές επιλογές + + + + API count method + Μέθοδος καταμέτρησης API + + + Close application Κλείσιμο αίτησης - - + + Browse... ξεφυλλίζω... - - + + Arguments: Επιχειρήματα: - + Mail Αλληλογραφία - + Use the preferences dialog in Thunderbird to select the accounts and folders Χρησιμοποιήστε το παράθυρο διαλόγου Προτιμήσεις Thunderbird για να επιλέξετε λογαριασμούς και φακέλους - + Debug Αποσφαλμάτωση - + Display debug window Προβολή παραθύρου αποσφαλμάτωσης @@ -413,40 +423,40 @@ Ελαχιστοποίηση στην περιοχή ειδοποιήσεων - + Apps Εφαρμογές - + Start application Εφαρμογή εκκίνησης - + Save Αποθήκευση - + Cancel Άκυρο - - + + Open Image Άνοιγμα εικόνας - - + + Image Files (*.png *.jpg *.bmp) Αρχεία εικόνας (*.png *.jpg *.bmp) - - + + Select application επιλέξτε εφαρμογή @@ -454,27 +464,27 @@ SysTrayX - + &Show/Hide &Εμφάνιση/Απόκρυψη - + &Preferences &Προτιμήσεις - + &About &Σχετικά - + &Quit &Έξοδος - + Close Κλείσιμο diff --git a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.en-US.qm b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.en-US.qm index 873ff16..d9d7a3b 100644 Binary files a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.en-US.qm and b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.en-US.qm differ diff --git a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.en-US.ts b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.en-US.ts index 00ae5bf..091fc9d 100644 --- a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.en-US.ts +++ b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.en-US.ts @@ -246,7 +246,7 @@ Invert icon - + Number properties Number properties @@ -255,67 +255,67 @@ Display unread message count - + Number color Number color - + Number size Number size - + Alignment Alignment - + Top left Top left - + Top centre Top centre - + Top right Top right - + Middle left Middle left - + Middle centre Middle centre - + Middle right Middle right - + Bottom left Bottom left - + Bottom centre Bottom centre - + Bottom right Bottom right - + Margins (left, top, right, bottom): Margins (left, top, right, bottom): @@ -355,79 +355,89 @@ New - + New indicator New indicator - + Icon round Icon round - + Icon star Icon star - + Shade Shade - + + Special options + Special options + + + + API count method + API count method + + + Apps Apps - + Close application Close application - - + + Browse... Browse... - - + + Arguments: Arguments: - + Start application Start application - + Mail Mail - + Use the preferences dialog in Thunderbird to select the accounts and folders Use the preferences dialog in Thunderbird to select the accounts and folders - + Debug Debug - + Display debug window Display debug window - + Save Save - + Cancel Cancel @@ -438,20 +448,20 @@ Minimize to tray - - + + Open Image Open Image - - + + Image Files (*.png *.jpg *.bmp) Image Files (*.png *.jpg *.bmp) - - + + Select application Select application @@ -459,27 +469,27 @@ SysTrayX - + &Show/Hide &Show/Hide - + &Preferences &Preferences - + &About &About - + &Quit &Quit - + Close Close diff --git a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.it.qm b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.it.qm index a6f53b6..d9b31e5 100644 Binary files a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.it.qm and b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.it.qm differ diff --git a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.it.ts b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.it.ts index cfef372..d79b66d 100644 --- a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.it.ts +++ b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.it.ts @@ -242,7 +242,7 @@ Icona inverti - + Number properties Proprietà numero @@ -251,67 +251,67 @@ Mostra numero di messaggi non letti - + Number color Colore numero - + Number size Dimensione numero - + Alignment Allineamento - + Top left A sinistra in alto - + Top centre In alto al centro - + Top right In alto a destra - + Middle left Al centro a sinistra - + Middle centre Centro centrale - + Middle right In mezzo a destra - + Bottom left In basso a sinistra - + Bottom centre In basso al centro - + Bottom right In basso a destra - + Margins (left, top, right, bottom): Margini (sinistra, in alto, destra, in basso): @@ -351,59 +351,69 @@ Nuovi - + New indicator Nuovo indicatore - + Icon round Icona rotonda - + Icon star Stella icona - + Shade Sfumatura - + + Special options + Opzioni speciali + + + + API count method + Metodo di conteggio API + + + Close application Applicazione alla chiusura - - + + Browse... Sfogliare... - - + + Arguments: Argomenti: - + Mail Messaggi - + Use the preferences dialog in Thunderbird to select the accounts and folders Usa la finestra di dialogo delle preferenze in Thunderbird per selezionare account e cartelle - + Debug Debug - + Display debug window Mostra finestra di debug @@ -414,40 +424,40 @@ Minimizza nel vassoio - + Apps Applicazioni - + Start application Applicazione di avvio - + Save Salva - + Cancel Annulla - - + + Open Image Apri immagine - - + + Image Files (*.png *.jpg *.bmp) File immagine (*.png *.jpg *.bmp) - - + + Select application Selezionare l'applicazione @@ -455,27 +465,27 @@ SysTrayX - + &Show/Hide &Mostra/Nascondi - + &Preferences &Preferenze - + &About &Informazioni - + &Quit &Esci - + Close Chiudi diff --git a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.nl.qm b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.nl.qm index d4bf1f8..a84f555 100644 Binary files a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.nl.qm and b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.nl.qm differ diff --git a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.nl.ts b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.nl.ts index a7812bc..66ce79b 100644 --- a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.nl.ts +++ b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.nl.ts @@ -245,7 +245,7 @@ Inverteer pictogram - + Number properties Nummer opties @@ -254,67 +254,67 @@ Aantal ongelezen berichten weergeven - + Number color Nummer kleur - + Number size Nummer grootte - + Alignment Uitlijning - + Top left Linksboven - + Top centre Middenboven - + Top right Rechtsboven - + Middle left Midden links - + Middle centre Midden midden - + Middle right Midden rechts - + Bottom left Linksonder - + Bottom centre Middenonder - + Bottom right Rechtsonder - + Margins (left, top, right, bottom): Marges (links, boven, rechts, onder): @@ -354,79 +354,89 @@ Nieuw - + New indicator Nieuw indicator - + Icon round Rond icoon - + Icon star Ster icoon - + Shade Tint - + + Special options + Speciale opties + + + + API count method + API tel methode + + + Apps Apps - + Close application Stop programma - - + + Browse... Bestand zoeken... - - + + Arguments: Argumenten: - + Start application Start programma - + Mail Berichten - + Use the preferences dialog in Thunderbird to select the accounts and folders Gebruik het voorkeurenvenster in Thunderbird om de accounts en mappen te selecteren - + Debug Debug - + Display debug window Toon debug venster - + Save Bewaren - + Cancel Annnuleren @@ -437,20 +447,20 @@ Minimaliseer naar systeemvak - - + + Open Image Open afbeelding - - + + Image Files (*.png *.jpg *.bmp) Afbeeldingsbestanden (*.png *.jpg *.bmp) - - + + Select application Selecteer programma @@ -458,27 +468,27 @@ SysTrayX - + &Show/Hide &Tonen/Verbergen - + &Preferences &Opties - + &About O&ver - + &Quit &Afsluiten - + Close Sluiten diff --git a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.pt-BR.qm b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.pt-BR.qm index bb196dd..c34eba4 100644 Binary files a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.pt-BR.qm and b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.pt-BR.qm differ diff --git a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.pt-BR.ts b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.pt-BR.ts index 9af89e3..7b84549 100644 --- a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.pt-BR.ts +++ b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.pt-BR.ts @@ -245,7 +245,7 @@ Ícone inverter - + Number properties Propriedades do número @@ -254,67 +254,67 @@ Exibir contador de mensagens não lidas - + Number color Cor do número - + Number size Tamanho do número - + Alignment Alinhamento - + Top left Canto superior esquerdo - + Top centre Centro superior - + Top right Canto superior direito - + Middle left Meio esquerdo - + Middle centre Centro médio - + Middle right Meio à direita - + Bottom left Canto inferior esquerdo - + Bottom centre Centro inferior - + Bottom right Canto inferior direito - + Margins (left, top, right, bottom): Margens (esquerdo, superior, direito, inferior): @@ -354,79 +354,89 @@ Novos - + New indicator Novo indicador - + Icon round Ícone redondo - + Icon star Ícone de estrela - + Shade Matiz - + + Special options + Opções especiais + + + + API count method + Método de contagem de API + + + Apps Aplicativos - + Close application Fechando aplicativo - - + + Browse... Procurar... - - + + Arguments: Argumentos: - + Start application Aplicativo de inicialização - + Mail E-mail - + Use the preferences dialog in Thunderbird to select the accounts and folders Use a janela de preferências no Thunderbird para selecionar as contas e pastas - + Debug Depuração - + Display debug window Mostrar janela de depuração - + Save Salvar - + Cancel Cancelar @@ -437,20 +447,20 @@ Minimizar para a tray - - + + Open Image Abrir imagem - - + + Image Files (*.png *.jpg *.bmp) Arquivo de imagem (*.png *.jpg *.bmp) - - + + Select application Selecione o aplicativo @@ -458,27 +468,27 @@ SysTrayX - + &Show/Hide &Exibir/Ocultar - + &Preferences &Preferências - + &About &Sobre - + &Quit &Sair - + Close Fechar diff --git a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.ru.qm b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.ru.qm index 41a0b45..745278d 100644 Binary files a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.ru.qm and b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.ru.qm differ diff --git a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.ru.ts b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.ru.ts index d65f648..50b5017 100644 --- a/app/SysTray-X/SysTray-X-app/languages/SysTray-X.ru.ts +++ b/app/SysTray-X/SysTray-X-app/languages/SysTray-X.ru.ts @@ -242,7 +242,7 @@ Инвертировать значок - + Number properties Настройки индикатора кол-ва @@ -251,67 +251,67 @@ Показывать кол-во непрочитанных писем - + Number color Цвет числа - + Number size Размер числа - + Alignment Выравнивание - + Top left Верхний левый - + Top centre Верхний центр - + Top right Верхний правый - + Middle left Средний левый - + Middle centre Средний центральный - + Middle right Средний правый - + Bottom left Нижний левый - + Bottom centre Нижний центральный - + Bottom right Нижний правый - + Margins (left, top, right, bottom): Отступ (левый, Верхний, правый, Нижний): @@ -351,79 +351,89 @@ Новые - + New indicator Новый индикатор - + Icon round Круглый значок - + Icon star Значок звезды - + Shade Оттенок - + + Special options + Специальные опции + + + + API count method + Метод подсчета API + + + Apps Программы - + Close application Заявление о закрытии - - + + Browse... просматривать... - - + + Arguments: аргументы: - + Start application Приложение при запуске - + Mail Письма - + Use the preferences dialog in Thunderbird to select the accounts and folders Используйте диалоговое окно настроек в Thunderbird, чтобы выбрать учетные записи и папки - + Debug Отладка - + Display debug window Показывать окно отладки - + Save Сохранить - + Cancel Отменить @@ -434,20 +444,20 @@ Свернуть в трей - - + + Open Image Открыть изображение - - + + Image Files (*.png *.jpg *.bmp) Файлы изображений (*.png *.jpg *.bmp) - - + + Select application выберите приложение @@ -455,27 +465,27 @@ SysTrayX - + &Show/Hide &Показать/Скрыть - + &Preferences &Настройки - + &About &О приложении - + &Quit &Выход - + Close Закрыть diff --git a/app/SysTray-X/SysTray-X-app/preferences.cpp b/app/SysTray-X/SysTray-X-app/preferences.cpp index e5a4a7a..36c472a 100644 --- a/app/SysTray-X/SysTray-X-app/preferences.cpp +++ b/app/SysTray-X/SysTray-X-app/preferences.cpp @@ -85,6 +85,8 @@ Preferences::Preferences( QObject *parent ) : QObject( parent ) m_version_hash = QLatin1String( APP_GITHASH ); m_version_branch = QLatin1String( APP_GITBRANCH ); + m_browser_version = "0.0.0"; + m_start_app = ""; m_start_app_args = ""; m_close_app = ""; @@ -913,6 +915,32 @@ void Preferences::setCloseAppArgs( QString args ) } +/* + * Get the API count method state. + */ +bool Preferences::getApiCountMethod() const +{ + return m_api_count_method; +} + + +/* + * Set the API count method state. + */ +void Preferences::setApiCountMethod( bool state ) +{ + if( m_api_count_method != state ) + { + m_api_count_method = state; + + /* + * Tell the world the new preference + */ + emit signalApiCountMethodChange(); + } +} + + /* * Get the debug state. */ diff --git a/app/SysTray-X/SysTray-X-app/preferences.h b/app/SysTray-X/SysTray-X-app/preferences.h index b4b6964..642019d 100644 --- a/app/SysTray-X/SysTray-X-app/preferences.h +++ b/app/SysTray-X/SysTray-X-app/preferences.h @@ -564,6 +564,20 @@ class Preferences : public QObject */ void setCloseAppArgs( QString args ); + /** + * @brief getApiCountMethod. Get the API count method state. + * + * @return The state. + */ + bool getApiCountMethod() const; + + /** + * @brief setApiCountMethod. Set the API count method state. + * + * @param state The state. + */ + void setApiCountMethod( bool state ); + /** * @brief getDebug. Get the debug windows state. * @@ -745,6 +759,11 @@ class Preferences : public QObject */ void signalCloseAppArgsChange(); + /** + * @brief signalApiCountMethodChange + */ + void signalApiCountMethodChange(); + private: /** @@ -931,6 +950,11 @@ class Preferences : public QObject */ QString m_close_app_args; + /** + * @brief m_api_count_method. The API count method state. + */ + bool m_api_count_method; + /** * @brief m_debug. Display debug window. */ diff --git a/app/SysTray-X/SysTray-X-app/preferences.ui b/app/SysTray-X/SysTray-X-app/preferences.ui index 17b3fcd..2a743e4 100644 --- a/app/SysTray-X/SysTray-X-app/preferences.ui +++ b/app/SysTray-X/SysTray-X-app/preferences.ui @@ -27,7 +27,7 @@ - 0 + 2 @@ -646,19 +646,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -919,6 +906,48 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Special options + + + + + + API count method + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + @@ -1154,12 +1183,12 @@ - - - - - - + + + + + + diff --git a/app/SysTray-X/SysTray-X-app/preferencesdialog.cpp b/app/SysTray-X/SysTray-X-app/preferencesdialog.cpp index 04bae40..88700d6 100644 --- a/app/SysTray-X/SysTray-X-app/preferencesdialog.cpp +++ b/app/SysTray-X/SysTray-X-app/preferencesdialog.cpp @@ -41,10 +41,10 @@ PreferencesDialog::PreferencesDialog( SysTrayXLink *link, Preferences *pref, QWi * Set close type button Ids */ m_ui->closeTypeGroup->setId( m_ui->defaultCloseWindowsRadioButton, Preferences::PREF_DEFAULT_CLOSE_WINDOWS); - m_ui->closeTypeGroup->setId( m_ui->minimizeMainCloseChildrenWindowsRadioButton, Preferences::PREF_MINIMIZE_MAIN_CLOSE_CHILDREN_WINDOWS ); - m_ui->closeTypeGroup->setId( m_ui->minimizeAllWindowsRadioButton, Preferences::PREF_MINIMIZE_ALL_WINDOWS ); m_ui->closeTypeGroup->setId( m_ui->minimizeMainTrayCloseChildrenWindowsRadioButton, Preferences::PREF_MINIMIZE_MAIN_TRAY_CLOSE_CHILDREN_WINDOWS ); m_ui->closeTypeGroup->setId( m_ui->minimizeAllTrayWindowsRadioButton, Preferences::PREF_MINIMIZE_ALL_WINDOWS_TRAY ); + m_ui->closeTypeGroup->setId( m_ui->minimizeMainCloseChildrenWindowsRadioButton, Preferences::PREF_MINIMIZE_MAIN_CLOSE_CHILDREN_WINDOWS ); + m_ui->closeTypeGroup->setId( m_ui->minimizeAllWindowsRadioButton, Preferences::PREF_MINIMIZE_ALL_WINDOWS ); /* * Set minimize type button Ids @@ -145,6 +145,11 @@ PreferencesDialog::PreferencesDialog( SysTrayXLink *link, Preferences *pref, QWi */ setStartupDelay( m_pref->getStartupDelay() ); + /* + * Set API count method + */ + setApiCountMethod( m_pref->getApiCountMethod() ); + /* * Set number alignment */ @@ -519,11 +524,30 @@ void PreferencesDialog::setCloseAppArgs( QString args ) } +/* + * Set the API count method state + */ +void PreferencesDialog::setApiCountMethod( bool state ) +{ + m_ui->apiCountMethod->setChecked( state ); +} + + /* * Handle show dialog signal */ void PreferencesDialog::slotShowDialog() { + QString version = m_pref->getBrowserVersion().split(".")[0]; + if( version.toInt() < 115 ) + { + m_ui->specialOptionsGroupBox->setVisible( false ); + } + else + { + m_ui->specialOptionsGroupBox->setVisible( true ); + } + showNormal(); activateWindow(); } @@ -561,6 +585,7 @@ void PreferencesDialog::slotAccept() m_pref->setShowNumber( m_ui->showNumberCheckBox->isChecked() ); m_pref->setShowNewIndicator( m_ui->showNewCheckBox->isChecked() ); m_pref->setStartupDelay( m_ui->startupDelaySpinBox->value() ); + m_pref->setApiCountMethod( m_ui->apiCountMethod->isChecked() ); m_pref->setCountType( static_cast< Preferences::CountType >( m_ui->countTypeGroup->checkedId() ) ); m_pref->setNumberSize( m_ui->numberSizeSpinBox->value() ); @@ -625,7 +650,8 @@ void PreferencesDialog::slotReject() setShowNumber( m_pref->getShowNumber() ); setShowNewIndicator( m_pref->getShowNewIndicator() ); - setStartupDelay( m_pref->getStartupDelay()); + setStartupDelay( m_pref->getStartupDelay() ); + setApiCountMethod( m_pref->getApiCountMethod() ); setCountType( m_pref->getCountType() ); setNumberColor( m_pref->getNumberColor() ); setNumberSize( m_pref->getNumberSize()); @@ -994,3 +1020,12 @@ void PreferencesDialog::slotCloseAppArgsChange() { setCloseAppArgs( m_pref->getCloseAppArgs() ); } + + +/* + * Handle the API count method change signal + */ +void PreferencesDialog::slotApiCountMethodChange() +{ + setApiCountMethod( m_pref->getApiCountMethod() ); +} diff --git a/app/SysTray-X/SysTray-X-app/preferencesdialog.h b/app/SysTray-X/SysTray-X-app/preferencesdialog.h index 91f73b2..546a44b 100644 --- a/app/SysTray-X/SysTray-X-app/preferencesdialog.h +++ b/app/SysTray-X/SysTray-X-app/preferencesdialog.h @@ -258,6 +258,12 @@ class PreferencesDialog : public QDialog */ void setCloseAppArgs( QString args ); + /** + * @brief setApiCountMethod. Set the API count method state. + * + * @param state The state. + */ + void setApiCountMethod( bool state ); signals: @@ -410,6 +416,11 @@ class PreferencesDialog : public QDialog */ void slotCloseAppArgsChange(); + /** + * @brief slotApiCountMethodChange. Slot for handling the API count methid change. + */ + void slotApiCountMethodChange(); + private slots: /** diff --git a/app/SysTray-X/SysTray-X-app/systrayx.cpp b/app/SysTray-X/SysTray-X-app/systrayx.cpp index 8450d5a..d3be0e1 100644 --- a/app/SysTray-X/SysTray-X-app/systrayx.cpp +++ b/app/SysTray-X/SysTray-X-app/systrayx.cpp @@ -140,6 +140,7 @@ SysTrayX::SysTrayX( QObject *parent ) : QObject( parent ) connect( m_preferences, &Preferences::signalStartAppArgsChange, m_pref_dialog, &PreferencesDialog::slotStartAppArgsChange ); connect( m_preferences, &Preferences::signalCloseAppChange, m_pref_dialog, &PreferencesDialog::slotCloseAppChange ); connect( m_preferences, &Preferences::signalCloseAppArgsChange, m_pref_dialog, &PreferencesDialog::slotCloseAppArgsChange ); + connect( m_preferences, &Preferences::signalApiCountMethodChange, m_pref_dialog, &PreferencesDialog::slotApiCountMethodChange ); connect( m_preferences, &Preferences::signalDebugChange, m_pref_dialog, &PreferencesDialog::slotDebugChange ); connect( m_preferences, &Preferences::signalDefaultIconTypeChange, m_link, &SysTrayXLink::slotDefaultIconTypeChange ); @@ -167,6 +168,7 @@ SysTrayX::SysTrayX( QObject *parent ) : QObject( parent ) connect( m_preferences, &Preferences::signalStartAppArgsChange, m_link, &SysTrayXLink::slotStartAppArgsChange ); connect( m_preferences, &Preferences::signalCloseAppChange, m_link, &SysTrayXLink::slotCloseAppChange ); connect( m_preferences, &Preferences::signalCloseAppArgsChange, m_link, &SysTrayXLink::slotCloseAppArgsChange ); + connect( m_preferences, &Preferences::signalApiCountMethodChange, m_link, &SysTrayXLink::slotApiCountMethodChange ); connect( m_preferences, &Preferences::signalDebugChange, m_link, &SysTrayXLink::slotDebugChange ); connect( m_preferences, &Preferences::signalHideDefaultIconChange, this, &SysTrayX::slotSelectIconObjectPref ); @@ -178,6 +180,8 @@ SysTrayX::SysTrayX( QObject *parent ) : QObject( parent ) connect( m_link, &SysTrayXLink::signalAddOnShutdown, this, &SysTrayX::slotAddOnShutdown ); connect( m_link, &SysTrayXLink::signalErrorAddOnShutdown, this, &SysTrayX::slotErrorAddOnShutdown ); connect( m_link, &SysTrayXLink::signalWindowState, m_win_ctrl, &WindowCtrl::slotWindowState ); + connect( m_link, &SysTrayXLink::signalNewWindow, m_win_ctrl, &WindowCtrl::slotNewWindow ); + connect( m_link, &SysTrayXLink::signalCloseWindow, m_win_ctrl, &WindowCtrl::slotCloseWindow ); connect( m_link, &SysTrayXLink::signalMailCount, this, &SysTrayX::slotMailCount ); connect( m_link, &SysTrayXLink::signalVersion, this, &SysTrayX::slotVersion ); connect( m_link, &SysTrayXLink::signalKdeIntegration, this, &SysTrayX::slotSelectIconObject ); @@ -204,6 +208,8 @@ SysTrayX::SysTrayX( QObject *parent ) : QObject( parent ) getPreferences(); /* + m_preferences->setBrowserVersion( "115.1.0" ); +// m_preferences->setBrowserVersion( "102.2.3" ); slotLoadLanguage( "en-US" ); //slotLoadLanguage( "it" ); //slotLoadLanguage( "nl" ); diff --git a/app/SysTray-X/SysTray-X-app/systrayxlink.cpp b/app/SysTray-X/SysTray-X-app/systrayxlink.cpp index 6c6a557..32f77a7 100644 --- a/app/SysTray-X/SysTray-X-app/systrayxlink.cpp +++ b/app/SysTray-X/SysTray-X-app/systrayxlink.cpp @@ -329,15 +329,11 @@ void SysTrayXLink::DecodeMessage( const QByteArray& message ) if( mailCount.contains( "unread" ) && mailCount[ "unread" ].isDouble() ) { unreadMail = mailCount[ "unread" ].toInt(); - - emit signalConsole( QString("Unread %1").arg( unreadMail ) ); } if( mailCount.contains( "new" ) && mailCount[ "new" ].isDouble() ) { newMail = mailCount[ "new" ].toInt(); - - emit signalConsole( QString("New %1").arg( newMail ) ); } emit signalMailCount( unreadMail, newMail ); @@ -362,9 +358,21 @@ void SysTrayXLink::DecodeMessage( const QByteArray& message ) emit signalAddOnShutdown(); } - if( jsonObject.contains( "window" ) && jsonObject[ "window" ].isString() ) + if( jsonObject.contains( "window" ) && jsonObject[ "window" ].isObject() ) { - QString window_state_str = jsonObject[ "window" ].toString(); + QJsonObject window = jsonObject[ "window" ].toObject(); + + QString window_state_str; + if( window.contains( "state" ) && window[ "state" ].isString() ) + { + window_state_str = window[ "state" ].toString(); + } + + int window_id = 0; + if( window.contains( "id" ) && window[ "id" ].isDouble() ) + { + window_id = window[ "id" ].toInt(); + } Preferences::WindowState window_state; if( window_state_str == Preferences::STATE_NORMAL_STR ) @@ -409,7 +417,7 @@ void SysTrayXLink::DecodeMessage( const QByteArray& message ) window_state = Preferences::STATE_NORMAL; } - emit signalWindowState( window_state ); + emit signalWindowState( window_state, window_id ); } if( jsonObject.contains( "hideDefaultIcon" ) && jsonObject[ "hideDefaultIcon" ].isBool() ) @@ -474,6 +482,32 @@ void SysTrayXLink::DecodeMessage( const QByteArray& message ) { emit signalCloseApp(); } + + if( jsonObject.contains( "newWindow" ) && jsonObject[ "newWindow" ].isDouble() ) + { + int new_window_id = jsonObject[ "newWindow" ].toInt(); + + emit signalNewWindow( new_window_id ); + } + + if( jsonObject.contains( "closeWindow" ) && jsonObject[ "closeWindow" ].isObject() ) + { + QJsonObject close_window = jsonObject[ "closeWindow" ].toObject(); + + int close_window_id = 0; + if( close_window.contains( "id" ) && close_window[ "id" ].isDouble() ) + { + close_window_id = close_window[ "id" ].toInt(); + } + + bool close_quit = false; + if( close_window.contains( "quit" ) && close_window[ "quit" ].isBool() ) + { + close_quit = close_window[ "quit" ].toBool(); + } + + emit signalCloseWindow( close_window_id, close_quit ); + } } } @@ -861,6 +895,16 @@ void SysTrayXLink::DecodePreferences( const QJsonObject& pref ) m_pref->setCloseAppArgs( args ); } + if( pref.contains( "apiCountMethod" ) && pref[ "apiCountMethod" ].isString() ) + { + bool api_count_method = pref[ "apiCountMethod" ].toString() == "true"; + + /* + * Store the new API cont method state + */ + m_pref->setApiCountMethod( api_count_method ); + } + if( pref.contains( "debug" ) && pref[ "debug" ].isString() ) { bool debug = pref[ "debug" ].toString() == "true"; @@ -876,27 +920,27 @@ void SysTrayXLink::DecodePreferences( const QJsonObject& pref ) /* * Decode preferences from JSON message */ -QMargins SysTrayXLink::DecodeMargins( const QJsonObject& marginsJson ) +QMargins SysTrayXLink::DecodeMargins( const QJsonObject& margins_json ) { QMargins margins; - if( marginsJson.contains( "left" ) && marginsJson[ "left" ].isString() ) + if( margins_json.contains( "left" ) && margins_json[ "left" ].isString() ) { - margins.setLeft( marginsJson[ "left" ].toString().toInt() ); + margins.setLeft( margins_json[ "left" ].toString().toInt() ); } - if( marginsJson.contains( "top" ) && marginsJson[ "top" ].isString() ) + if( margins_json.contains( "top" ) && margins_json[ "top" ].isString() ) { - margins.setTop( marginsJson[ "top" ].toString().toInt() ); + margins.setTop( margins_json[ "top" ].toString().toInt() ); } - if( marginsJson.contains( "right" ) && marginsJson[ "right" ].isString() ) + if( margins_json.contains( "right" ) && margins_json[ "right" ].isString() ) { - margins.setRight( marginsJson[ "right" ].toString().toInt() ); + margins.setRight( margins_json[ "right" ].toString().toInt() ); } - if( marginsJson.contains( "bottom" ) && marginsJson[ "bottom" ].isString() ) + if( margins_json.contains( "bottom" ) && margins_json[ "bottom" ].isString() ) { - margins.setBottom( marginsJson[ "bottom" ].toString().toInt() ); + margins.setBottom( margins_json[ "bottom" ].toString().toInt() ); } return margins; @@ -941,6 +985,7 @@ void SysTrayXLink::EncodePreferences( const Preferences& pref ) prefObject.insert("numberMargins", marginsObject ); prefObject.insert("countType", QJsonValue::fromVariant( QString::number( pref.getCountType() ) ) ); prefObject.insert("startupDelay", QJsonValue::fromVariant( QString::number( pref.getStartupDelay() ) ) ); + prefObject.insert("apiCountMethod", QJsonValue::fromVariant( QString( pref.getApiCountMethod() ? "true" : "false" ) ) ); prefObject.insert("startApp", QJsonValue::fromVariant( pref.getStartApp() ) ); prefObject.insert("startAppArgs", QJsonValue::fromVariant( pref.getStartAppArgs() ) ); @@ -1287,6 +1332,17 @@ void SysTrayXLink::slotCloseAppArgsChange() } +/* + * Handle a API count method change signal + */ +void SysTrayXLink::slotApiCountMethodChange() +{ + if( m_pref->getAppPrefChanged() ) + { + sendPreferences(); + } +} + /* * Handle a debug state change signal */ diff --git a/app/SysTray-X/SysTray-X-app/systrayxlink.h b/app/SysTray-X/SysTray-X-app/systrayxlink.h index 7c49fdb..121b2e8 100644 --- a/app/SysTray-X/SysTray-X-app/systrayxlink.h +++ b/app/SysTray-X/SysTray-X-app/systrayxlink.h @@ -7,7 +7,6 @@ */ #include "preferences.h" - /* * Qt includes */ @@ -213,7 +212,7 @@ class SysTrayXLink : public QObject /** * @brief signalWindowState. Signal a change in the window state. */ - void signalWindowState( Preferences::WindowState state ); + void signalWindowState( Preferences::WindowState state, int id ); /** * @brief signalKdeIntegration. Signal KDE integration (and use the KStatusNotifierItem icon) @@ -252,6 +251,21 @@ class SysTrayXLink : public QObject */ void signalCloseApp(); + /** + * @brief signalNewWindow. Signal the new window id. + * + * @param id TB id of the window. + */ + void signalNewWindow( int id ); + + /** + * @brief signalCloseWindow. Signal the close window id. + * + * @param id TB id of the window. + * @param quit true if the window is really closed. + */ + void signalCloseWindow( int id, bool quit ); + public slots: /** @@ -389,6 +403,11 @@ class SysTrayXLink : public QObject */ void slotCloseAppArgsChange(); + /** + * @brief slotApiCountMethodChange. Slot for handling the API count method change signals. + */ + void slotApiCountMethodChange(); + private slots: /** diff --git a/app/SysTray-X/SysTray-X-app/windowctrl-unix.cpp b/app/SysTray-X/SysTray-X-app/windowctrl-unix.cpp index cbf77e3..1d7cd76 100644 --- a/app/SysTray-X/SysTray-X-app/windowctrl-unix.cpp +++ b/app/SysTray-X/SysTray-X-app/windowctrl-unix.cpp @@ -6,10 +6,6 @@ * Local includes */ #include "debug.h" - -/* - * Local includes - */ #include "preferences.h" /* @@ -38,8 +34,10 @@ WindowCtrlUnix::WindowCtrlUnix( QObject *parent ) : QObject( parent ) * Initialize */ m_tb_windows = QList< quint64 >(); + m_tb_window_refs = QMap< int, quint64 >(); m_tb_window_positions = QMap< quint64, QPoint >(); m_tb_window_states = QMap< quint64, Preferences::WindowState >(); + m_tb_window_states_x11 = QMap< quint64, QStringList >(); m_tb_window_hints = QMap< quint64, SizeHints >(); /* @@ -267,15 +265,77 @@ void WindowCtrlUnix::findWindows( qint64 pid ) } +/* + * Try to match the TB window id to a x11 window + */ +void WindowCtrlUnix::identifyWindow( int id ) +{ + /* + * Get all the windows connected to TB + */ + findWindows( getPpid() ); + + /* + * Get the list + */ + QList win_list = m_tb_windows; + + /* + * Remove known ids + */ + QMapIterator it(m_tb_window_refs); + while (it.hasNext()) { + it.next(); + + int found = win_list.indexOf( it.value() ); + if( found != -1 ) + { + win_list.removeAt( found ); + } + } + + /* + * Should only one remain + */ + if( win_list.length() > 0 ) + { + m_tb_window_refs[ id ] = win_list[ 0 ]; + } + + if( win_list.length() != 1 ) + { +// emit signalConsole( QString( "Unexpected Ids: %1" ).arg( win_list.length() ) ); + } +} + + /* * Get the Thunderbird window IDs */ -QList< quint64 > WindowCtrlUnix::getWinIds() +const QList< quint64 >& WindowCtrlUnix::getWinIds() const { return m_tb_windows; } +/* + * Get the reference IDs + */ +const QMap< int, quint64 >& WindowCtrlUnix::getRefIds() const +{ + return m_tb_window_refs; +} + + +/* + * Get the reference IDs + */ +void WindowCtrlUnix::removeRefId( int id ) +{ + m_tb_window_refs.remove( id ); +} + + /* * Get the states of the TB windows. */ @@ -299,15 +359,25 @@ void WindowCtrlUnix::updatePositions() { quint64 window = m_tb_windows.at( i ); + QStringList x11_state = getWindowStateX11( window ); + if( x11_state.contains( "_NET_WM_STATE_MAXIMIZED_VERT" ) && + x11_state.contains( "_NET_WM_STATE_MAXIMIZED_HORZ" ) ) + { + /* + * Maximized, skip position store + */ + continue; + } + if( m_tb_window_states[ window ] != Preferences::STATE_MINIMIZED && m_tb_window_states[ window ] != Preferences::STATE_DOCKED ) { /* * Get border / title bar sizes */ - long left; - long top; - long right; - long bottom; + int left; + int top; + int right; + int bottom; GetWindowFrameExtensions( m_display, window, &left, &top, &right, &bottom ); #ifdef DEBUG_DISPLAY_ACTIONS_DETAILS @@ -317,8 +387,8 @@ void WindowCtrlUnix::updatePositions() /* * Get the position */ - long x; - long y; + int x; + int y; GetWindowPosition( m_display, window, &x, &y ); /* @@ -367,6 +437,11 @@ void WindowCtrlUnix::minimizeWindowToTaskbar( quint64 window ) */ GetWMNormalHints( m_display, window, &m_tb_window_hints[ window ] ); + /* + * Get and store the X11 window state + */ + m_tb_window_states_x11[ window ] = getWindowStateX11( window ); + /* * Minimize the window */ @@ -407,6 +482,11 @@ void WindowCtrlUnix::minimizeWindowToTray( quint64 window ) */ GetWMNormalHints( m_display, window, &m_tb_window_hints[ window ] ); + /* + * Get and store the X11 window state + */ + m_tb_window_states_x11[ window ] = getWindowStateX11( window );; + /* * Set the flags (GNOME, Wayland?) */ @@ -452,14 +532,31 @@ void WindowCtrlUnix::normalizeWindow( quint64 window ) { MapWindow( m_display, window ); - SetWMNormalHints( m_display, window, m_tb_window_hints[ window ] ); - /* * Reset the hide flags */ SendEvent( m_display, window, "_NET_WM_STATE", _NET_WM_STATE_REMOVE, _ATOM_SKIP_TASKBAR ); SendEvent( m_display, window, "_NET_WM_STATE", _NET_WM_STATE_REMOVE, _ATOM_SKIP_PAGER ); + /* + * Was the window maximized? + */ + if( m_tb_window_states_x11[ window ].contains( "_NET_WM_STATE_MAXIMIZED_VERT" ) && + m_tb_window_states_x11[ window ].contains( "_NET_WM_STATE_MAXIMIZED_HORZ" ) ) + { + SendEvent( m_display, window, "_NET_WM_STATE", _NET_WM_STATE_ADD, _ATOM_MAXIMIZED ); + } + + /* + * Delete the X11 state + */ + m_tb_window_states_x11.remove( window ); + + /* + * Restore the size hints + */ + SetWMNormalHints( m_display, window, m_tb_window_hints[ window ] ); + Flush( m_display ); } @@ -622,4 +719,42 @@ QList< WindowCtrlUnix::WindowItem > WindowCtrlUnix::listXWindows( void* displa return windows; } + +/* + * Get the window state from X11 + */ +QStringList WindowCtrlUnix::getWindowStateX11( quint64 window ) +{ + qint32 n_net_wm_state; + void* net_wm_state_ptr = GetWindowProperty( m_display, window, "_NET_WM_STATE", &n_net_wm_state ); + + /* + * Get the atoms + */ + QStringList atom_list; + if( net_wm_state_ptr != nullptr ) + { + for( qint32 i = 0 ; i < n_net_wm_state ; ++i ) + { + char* atom_name = GetAtomName( m_display, reinterpret_cast( net_wm_state_ptr )[ i ] ); + + atom_list.append( atom_name ); + + if( atom_name ) + { + Free( atom_name ); + } + } + + Free( net_wm_state_ptr ); + } +/* + for( int i = 0 ; i < atom_list.length() ; ++i ) + { + emit signalConsole( QString( "Atom: %1").arg( atom_list.at( i ) ) ); + } +*/ + return atom_list; +} + #endif // Q_OS_UNIX diff --git a/app/SysTray-X/SysTray-X-app/windowctrl-unix.h b/app/SysTray-X/SysTray-X-app/windowctrl-unix.h index def2df2..cca964f 100644 --- a/app/SysTray-X/SysTray-X-app/windowctrl-unix.h +++ b/app/SysTray-X/SysTray-X-app/windowctrl-unix.h @@ -21,6 +21,7 @@ #include #include #include +#include /* * Predefines @@ -222,12 +223,33 @@ class WindowCtrlUnix : public QObject */ void findWindows( qint64 pid ); + /** + * @brief identifyWindow. Try to connect th TB window id to a X11 window. + * + * @param id The TB windows id. + */ + void identifyWindow( int id ); + /** * @brief getWinIds. Get the Thunderbird window IDs. * * @return The list of window ID. */ - QList< quint64 > getWinIds(); + const QList< quint64 >& getWinIds() const; + + /** + * @brief removeRefId. Remove the TB window Id from the reference list. + * + * @param id The TB window id. + */ + void removeRefId( int id ); + + /** + * @brief getRefIds. Get the reference IDs. + * + * @return The list of reference IDs. + */ + const QMap< int, quint64 >& getRefIds() const; /** * @brief getWindowState. Get the state of a TB windows. @@ -238,15 +260,6 @@ class WindowCtrlUnix : public QObject */ const Preferences::WindowState& getWindowState( const quint64 window ); - /** - * @brief getWindowState. Get the state of a TB windows. - * - * @param window Window ID. - * - * @return The window state. - */ - const Preferences::WindowState& getWindowStateX11( const quint64 window ); - /** * @brief updatePositions. Update the window positions. */ @@ -287,11 +300,6 @@ class WindowCtrlUnix : public QObject */ void setPositions( QList< QPoint > window_positions ); - /** - * @brief updateX11WindowStates. Update the x11 window states. - */ - void updateX11WindowStates( CheckType check_type ); - private: /** @@ -310,6 +318,13 @@ class WindowCtrlUnix : public QObject */ QList< WindowItem > listXWindows( void* display, quint64 window, int level = 0 ); + /** + * @brief getWindowStateX11. Get the window state from X11 + * + * @param window The window. + */ + QStringList getWindowStateX11( quint64 window ); + signals: /** @@ -338,6 +353,11 @@ class WindowCtrlUnix : public QObject */ QList< quint64 > m_tb_windows; + /** + * @brief m_tb_window_refs. The Thunderbird window ids referenced to x11 windows. + */ + QMap< int, quint64 > m_tb_window_refs; + /** * @brief m_tb_window_positions. The Thunderbird window positions. */ @@ -348,6 +368,11 @@ class WindowCtrlUnix : public QObject */ QMap< quint64, Preferences::WindowState > m_tb_window_states; + /** + * @brief m_tb_window_states_x11. The Thunderbird window states X11. + */ + QMap< quint64, QStringList > m_tb_window_states_x11; + /** * @brief m_tb_window_hints. The Thunderbird window hints. */ diff --git a/app/SysTray-X/SysTray-X-app/windowctrl.cpp b/app/SysTray-X/SysTray-X-app/windowctrl.cpp index b9bd7ac..42dd4f8 100644 --- a/app/SysTray-X/SysTray-X-app/windowctrl.cpp +++ b/app/SysTray-X/SysTray-X-app/windowctrl.cpp @@ -152,7 +152,7 @@ void WindowCtrl::slotStartMinimizedChange() /* * Handle change in window state */ -void WindowCtrl::slotWindowState( Preferences::WindowState state ) +void WindowCtrl::slotWindowState( Preferences::WindowState state, int id ) { if( m_show_hide_active ) { @@ -163,7 +163,8 @@ void WindowCtrl::slotWindowState( Preferences::WindowState state ) } #ifdef DEBUG_DISPLAY_ACTIONS - emit signalConsole( QString( "State change to: %1" ).arg( Preferences::WindowStateString.at( state ) ) ); + emit signalConsole( QString( "State: %1" ).arg( Preferences::WindowStateString.at( state ) ) ); + emit signalConsole( QString( "Id: %1" ).arg( id ) ); #endif /* @@ -185,7 +186,7 @@ void WindowCtrl::slotWindowState( Preferences::WindowState state ) /* * Minimize on startup always to the tray */ - TargetType targetType = TargetType::TYPE_WINDOW_TO_SYSTEMTRAY; + TargetType target_type = TargetType::TYPE_WINDOW_TO_SYSTEMTRAY; if( state == Preferences::STATE_MINIMIZED_ALL ) { @@ -201,10 +202,10 @@ void WindowCtrl::slotWindowState( Preferences::WindowState state ) /* * Minimize target on close depends on preference */ - Preferences::CloseType closeType = getCloseType(); - if( closeType == Preferences::PREF_MINIMIZE_ALL_WINDOWS || closeType == Preferences::PREF_MINIMIZE_MAIN_CLOSE_CHILDREN_WINDOWS ) + Preferences::CloseType close_type = getCloseType(); + if( close_type == Preferences::PREF_MINIMIZE_ALL_WINDOWS || close_type == Preferences::PREF_MINIMIZE_MAIN_CLOSE_CHILDREN_WINDOWS ) { - targetType = TargetType::TYPE_WINDOW_TO_TASKBAR; + target_type = TargetType::TYPE_WINDOW_TO_TASKBAR; } } @@ -219,7 +220,7 @@ void WindowCtrl::slotWindowState( Preferences::WindowState state ) .arg( Preferences::WindowStateString.at( getWindowState( win_ids.at( i ) ) ) ) ); #endif - if( targetType == TargetType::TYPE_WINDOW_TO_TASKBAR ) + if( target_type == TargetType::TYPE_WINDOW_TO_TASKBAR ) { minimizeWindowToTaskbar( win_ids.at( i ) ); } @@ -231,20 +232,21 @@ void WindowCtrl::slotWindowState( Preferences::WindowState state ) } else { - if( state == Preferences::STATE_MINIMIZED ) + if( state == Preferences::STATE_MINIMIZED || state == Preferences::STATE_DOCKED ) { - Preferences::MinimizeType minimizeType = getMinimizeType(); - if( minimizeType != Preferences::PREF_DEFAULT_MINIMIZE ) + Preferences::MinimizeType minimize_type = getMinimizeType(); + if( minimize_type != Preferences::PREF_DEFAULT_MINIMIZE ) { - QList< quint64 > win_ids = getWinIds(); - for( int i = 0 ; i < win_ids.length() ; ++i ) - { - /* - * Hide the window - */ - if( getWindowState( win_ids[ i ] ) == Preferences::STATE_MINIMIZED ) + QMap< int, quint64 > ref_list = getRefIds(); + + if( ref_list.contains( id ) ) + { + /* + * Hide the window + */ + if( getWindowState( ref_list[ id ] ) == Preferences::STATE_MINIMIZED ) { - minimizeWindowToTray( win_ids.at( i ) ); + minimizeWindowToTray( ref_list[ id ] ); } } } @@ -294,10 +296,10 @@ void WindowCtrl::slotShowHide() #endif - TargetType targetType = TargetType::TYPE_WINDOW_TO_SYSTEMTRAY; + TargetType target_type = TargetType::TYPE_WINDOW_TO_SYSTEMTRAY; if( getMinimizeIconType() == Preferences::PREF_DEFAULT_MINIMIZE_ICON ) { - targetType = TargetType::TYPE_WINDOW_TO_TASKBAR; + target_type = TargetType::TYPE_WINDOW_TO_TASKBAR; } /* @@ -319,7 +321,7 @@ void WindowCtrl::slotShowHide() } else { - if( targetType == TargetType::TYPE_WINDOW_TO_TASKBAR ) + if( target_type == TargetType::TYPE_WINDOW_TO_TASKBAR ) { minimizeWindowToTaskbar( win_ids.at( i ) ); } @@ -395,3 +397,51 @@ void WindowCtrl::slotPositions( QList< QPoint > window_positions ) #endif } + + +/* + * Handle the new window id. + */ +void WindowCtrl::slotNewWindow( int id ) +{ + /* + * Get the windows + */ + findWindows( m_ppid ); + + /* + * Try to find a corresponding x11 window + */ + identifyWindow( id ); +} + + +/* + * Handle the close window id. + */ +void WindowCtrl::slotCloseWindow( int id, bool quit ) +{ + if( quit ) + { + /* + * Window is closed by TB + */ + removeRefId( id ); + return; + } + + QMap ref_list = getRefIds(); + if( ref_list.contains( id ) ) + { + Preferences::CloseType close_type = getCloseType(); + if( close_type == Preferences::PREF_MINIMIZE_MAIN_TRAY_CLOSE_CHILDREN_WINDOWS || + close_type == Preferences::PREF_MINIMIZE_ALL_WINDOWS_TRAY ) + { + minimizeWindowToTray( ref_list[ id ] ); + } + else + { + minimizeWindowToTaskbar( ref_list[ id ] ); + } + } +} diff --git a/app/SysTray-X/SysTray-X-app/windowctrl.h b/app/SysTray-X/SysTray-X-app/windowctrl.h index 9dd2945..699c9a2 100644 --- a/app/SysTray-X/SysTray-X-app/windowctrl.h +++ b/app/SysTray-X/SysTray-X-app/windowctrl.h @@ -1,8 +1,15 @@ #ifndef WINDOWCTRL_H #define WINDOWCTRL_H +/* + * Qt includes + */ #include + +/* + * Local includes + */ #ifdef Q_OS_UNIX #include "windowctrl-unix.h" #endif // Q_OS_UNIX @@ -99,9 +106,10 @@ class WindowCtrl : public QObject /** * @brief slotWindowState. Handle the window state change signal. * - * @param state The new state. + * @param state The new state. + * @param id The TB window id. */ - void slotWindowState( Preferences::WindowState state ); + void slotWindowState( Preferences::WindowState state, int id); /** * @brief slotShowHide. Slot for handling of the show / hide window signal. @@ -118,6 +126,21 @@ class WindowCtrl : public QObject */ void slotPositions( QList< QPoint > window_positions ); + /** + * @brief slotNewWindow. Slot for handling a new window. + * + * @param id The TB window id. + */ + void slotNewWindow( int id ); + + /** + * @brief slotCloseWindow. Slot for handling a close window. + * + * @param id The TB window id. + * @param quit true if the window is really closed. + */ + void slotCloseWindow( int id, bool quit ); + private: /** diff --git a/app/SysTray-X/SysTray-X-lib-x11/systray-x-lib-x11.cpp b/app/SysTray-X/SysTray-X-lib-x11/systray-x-lib-x11.cpp index d5b7e0a..f381cdd 100644 --- a/app/SysTray-X/SysTray-X-lib-x11/systray-x-lib-x11.cpp +++ b/app/SysTray-X/SysTray-X-lib-x11/systray-x-lib-x11.cpp @@ -352,6 +352,25 @@ void SendEvent( void* display, quint64 window, const char* msg_type, break; } + case _ATOM_MAXIMIZED_VERT: + { + event.xclient.data.l[1] = XInternAtom( dsp, "_NET_WM_STATE_MAXIMIZED_VERT", False ); + break; + } + + case _ATOM_MAXIMIZED_HORZ: + { + event.xclient.data.l[1] = XInternAtom( dsp, "_NET_WM_STATE_MAXIMIZED_HORZ", False ); + break; + } + + case _ATOM_MAXIMIZED: + { + event.xclient.data.l[1] = XInternAtom( dsp, "_NET_WM_STATE_MAXIMIZED_VERT", False ); + event.xclient.data.l[2] = XInternAtom( dsp, "_NET_WM_STATE_MAXIMIZED_HORZ", False ); + break; + } + default: { return; @@ -394,7 +413,7 @@ void SendEvent( void* display, quint64 window, const char* msg_type, /* * Get the frame extensions */ -void GetWindowFrameExtensions( void *display, quint64 window, long* left, long* top, long* right, long* bottom ) +void GetWindowFrameExtensions( void *display, quint64 window, int* left, int* top, int* right, int* bottom ) { Display* dsp = (Display*)display; @@ -424,10 +443,10 @@ void GetWindowFrameExtensions( void *display, quint64 window, long* left, lon if( list && len == 4 ) { long* extents = (long*)list; - *left = extents[ 0 ]; - *right = extents[ 1 ]; - *top = extents[ 2 ]; - *bottom = extents[ 3 ]; + *left = (int)extents[ 0 ]; + *right = (int)extents[ 1 ]; + *top = (int)extents[ 2 ]; + *bottom = (int)extents[ 3 ]; } } @@ -441,7 +460,7 @@ void GetWindowFrameExtensions( void *display, quint64 window, long* left, lon /* * Get the window position */ -void GetWindowPosition( void* display, quint64 window, long* pos_x, long* pos_y ) +void GetWindowPosition( void* display, quint64 window, int* pos_x, int* pos_y ) { Display* dsp = (Display*)display; @@ -456,6 +475,37 @@ void GetWindowPosition( void* display, quint64 window, long* pos_x, long* pos } +/* + * Get the window rect + */ +void GetWindowRectangle( void* display, quint64 window, int* win_x, int* win_y, int* win_width, int* win_height ) +{ + /* + * Get border / title bar sizes + */ + int left; + int top; + int right; + int bottom; + GetWindowFrameExtensions( display, window, &left, &top, &right, &bottom ); + + /* + * Get position and attributes + */ + Display* dsp = (Display*)display; + + int x, y; + Window child; + XWindowAttributes xwa; + XTranslateCoordinates( dsp, window, XDefaultRootWindow( dsp ), 0, 0, &x, &y, &child ); + XGetWindowAttributes( dsp, window, &xwa ); + + *win_x = x - xwa.x - left; + *win_y = y - xwa.y - top; + *win_width = xwa.width + left + right; + *win_height = xwa.height + top + bottom; +} + /* * Set the window position */ diff --git a/app/SysTray-X/SysTray-X-lib-x11/systray-x-lib-x11.h b/app/SysTray-X/SysTray-X-lib-x11/systray-x-lib-x11.h index 4f7b789..a99b77f 100644 --- a/app/SysTray-X/SysTray-X-lib-x11/systray-x-lib-x11.h +++ b/app/SysTray-X/SysTray-X-lib-x11/systray-x-lib-x11.h @@ -36,10 +36,12 @@ enum StateActions enum StateAtoms { _ATOM_SKIP_TASKBAR = 0, - _ATOM_SKIP_PAGER + _ATOM_SKIP_PAGER, + _ATOM_MAXIMIZED_VERT, + _ATOM_MAXIMIZED_HORZ, + _ATOM_MAXIMIZED }; - /* * Protocol atoms */ @@ -239,7 +241,7 @@ void SendEvent( void* display, quint64 window, const char* msg_type, * @param right Storage for the right extension size * @param bottom Storage for the bottom extension size */ -void GetWindowFrameExtensions( void *display, quint64 window, long* left, long* top, long* right, long* bottom ); +void GetWindowFrameExtensions( void *display, quint64 window, int* left, int* top, int* right, int* bottom ); /** * @brief GetWindowPosition. Get the window position. @@ -249,7 +251,19 @@ void GetWindowFrameExtensions( void *display, quint64 window, long* left, lon * @param pos_x Storage for the x coordinate * @param pos_y Storage for the y coordinate */ -void GetWindowPosition( void *display, quint64 window, long* pos_x, long* pos_y ); +void GetWindowPosition( void *display, quint64 window, int* pos_x, int* pos_y ); + +/** + * @brief GetWindowRectangle. Get the window rectangle. + * + * @param display The display + * @param window The window + * @param win_x The x coordinate + * @param win_y The y coordinete + * @param win_width The width + * @param win_height The height + */ +void GetWindowRectangle( void* display, quint64 window, int* win_x, int* win_y, int* win_width, int* win_height ); /** * @brief MoveWindow. Set the window position. diff --git a/create_linux_gnome_installers.sh b/create_linux_gnome_installers.sh index 6d5b564..11c6629 100755 --- a/create_linux_gnome_installers.sh +++ b/create_linux_gnome_installers.sh @@ -18,7 +18,7 @@ OBS_RPM_PKS="" OBS_RPM_GNOME_EXT="" OBS_RPM_ARCHS+="openSUSE_Leap_15.4/x86_64 " OBS_RPM_PKS+="_ " -OBS_RPM_GNOME_EXT+="master " +OBS_RPM_GNOME_EXT+="v53 " OBS_RPM_ARCHS+="openSUSE_Tumbleweed/i586 " OBS_RPM_PKS+="tmblwd " OBS_RPM_GNOME_EXT+="master " @@ -27,19 +27,19 @@ OBS_RPM_PKS+="tmblwd " OBS_RPM_GNOME_EXT+="master " OBS_RPM_ARCHS+="15.4/x86_64 " OBS_RPM_PKS+="lp154 " -OBS_RPM_GNOME_EXT+="master " +OBS_RPM_GNOME_EXT+="v53 " OBS_RPM_ARCHS+="15.5/x86_64 " OBS_RPM_PKS+="lp155 " -OBS_RPM_GNOME_EXT+="master " +OBS_RPM_GNOME_EXT+="v53 " OBS_RPM_ARCHS+="Fedora_36/x86_64 " OBS_RPM_PKS+="fed36 " -OBS_RPM_GNOME_EXT+="master " +OBS_RPM_GNOME_EXT+="v53 " OBS_RPM_ARCHS+="Fedora_37/x86_64 " OBS_RPM_PKS+="fed37 " -OBS_RPM_GNOME_EXT+="master " +OBS_RPM_GNOME_EXT+="v53 " OBS_RPM_ARCHS+="Fedora_38/x86_64 " OBS_RPM_PKS+="fed38 " -OBS_RPM_GNOME_EXT+="master " +OBS_RPM_GNOME_EXT+="v53 " OBS_RPM_ARCHS+="Fedora_39/x86_64 " OBS_RPM_PKS+="fed39 " OBS_RPM_GNOME_EXT+="master " @@ -121,6 +121,7 @@ create_gnome_extension_tar() { if [ ${GNOME_EXT} != "v26" ] && [ ${GNOME_EXT} != "v34" ] && [ ${GNOME_EXT} != "v46" ] && + [ ${GNOME_EXT} != "v53" ] && [ ${GNOME_EXT} != "master" ] ; then return fi diff --git a/create_linux_staging_gnome_installers.sh b/create_linux_staging_gnome_installers.sh index 41e0a44..3be390b 100755 --- a/create_linux_staging_gnome_installers.sh +++ b/create_linux_staging_gnome_installers.sh @@ -18,7 +18,7 @@ OBS_RPM_PKS="" OBS_RPM_GNOME_EXT="" OBS_RPM_ARCHS+="openSUSE_Leap_15.4/x86_64 " OBS_RPM_PKS+="_ " -OBS_RPM_GNOME_EXT+="master " +OBS_RPM_GNOME_EXT+="v53 " OBS_RPM_ARCHS+="openSUSE_Tumbleweed/i586 " OBS_RPM_PKS+="tmblwd " OBS_RPM_GNOME_EXT+="master " @@ -27,19 +27,19 @@ OBS_RPM_PKS+="tmblwd " OBS_RPM_GNOME_EXT+="master " OBS_RPM_ARCHS+="15.4/x86_64 " OBS_RPM_PKS+="lp154 " -OBS_RPM_GNOME_EXT+="master " +OBS_RPM_GNOME_EXT+="v53 " OBS_RPM_ARCHS+="15.5/x86_64 " OBS_RPM_PKS+="lp155 " -OBS_RPM_GNOME_EXT+="master " +OBS_RPM_GNOME_EXT+="v53 " OBS_RPM_ARCHS+="Fedora_36/x86_64 " OBS_RPM_PKS+="fed36 " -OBS_RPM_GNOME_EXT+="master " +OBS_RPM_GNOME_EXT+="v53 " OBS_RPM_ARCHS+="Fedora_37/x86_64 " OBS_RPM_PKS+="fed37 " -OBS_RPM_GNOME_EXT+="master " +OBS_RPM_GNOME_EXT+="v53 " OBS_RPM_ARCHS+="Fedora_38/x86_64 " OBS_RPM_PKS+="fed38 " -OBS_RPM_GNOME_EXT+="master " +OBS_RPM_GNOME_EXT+="v53 " OBS_RPM_ARCHS+="Fedora_39/x86_64 " OBS_RPM_PKS+="fed39 " OBS_RPM_GNOME_EXT+="master " @@ -121,6 +121,7 @@ create_gnome_extension_tar() { if [ "${GNOME_EXT}" != "v26" ] && [ "${GNOME_EXT}" != "v34" ] && [ "${GNOME_EXT}" != "v46" ] && + [ "${GNOME_EXT}" != "v53" ] && [ "${GNOME_EXT}" != "master" ] ; then return fi diff --git a/dist/SysTray-X-32bit.nsi b/dist/SysTray-X-32bit.nsi index 538634e..acf2436 100644 --- a/dist/SysTray-X-32bit.nsi +++ b/dist/SysTray-X-32bit.nsi @@ -11,7 +11,7 @@ Name "${Name}" !define PRODUCT_ID "systray-x@Ximi1970" !define VERSIONMAJOR 0 !define VERSIONMINOR 9 -!define VERSIONBUILD 6 +!define VERSIONBUILD 7 !define VERSION "${VERSIONMAJOR}.${VERSIONMINOR}.${VERSIONBUILD}" CRCCheck On diff --git a/dist/SysTray-X-64bit.nsi b/dist/SysTray-X-64bit.nsi index 2966c58..4688ef3 100644 --- a/dist/SysTray-X-64bit.nsi +++ b/dist/SysTray-X-64bit.nsi @@ -11,7 +11,7 @@ Name "${Name}" !define PRODUCT_ID "systray-x@Ximi1970" !define VERSIONMAJOR 0 !define VERSIONMINOR 9 -!define VERSIONBUILD 6 +!define VERSIONBUILD 7 !define VERSION "${VERSIONMAJOR}.${VERSIONMINOR}.${VERSIONBUILD}" CRCCheck On diff --git a/dist/deb/gnome/debian.changelog b/dist/deb/gnome/debian.changelog index bf966aa..544f189 100644 --- a/dist/deb/gnome/debian.changelog +++ b/dist/deb/gnome/debian.changelog @@ -1,3 +1,10 @@ +systray-x-gnome (0.9.7-0) unstable; urgency=low + + * Update to 0.9.7 + + - Added option for new TB115 mail counting (slow with new mails enabled) + - Bugfixes + systray-x-gnome (0.9.6-0) unstable; urgency=low * Update to 0.9.6 diff --git a/dist/deb/kde/debian.changelog b/dist/deb/kde/debian.changelog index 6f8c9cc..94256ab 100644 --- a/dist/deb/kde/debian.changelog +++ b/dist/deb/kde/debian.changelog @@ -1,3 +1,10 @@ +systray-x (0.9.7-0) unstable; urgency=low + + * Update to 0.9.7 + + - Added option for new TB115 mail counting (slow with new mails enabled) + - Bugfixes + systray-x (0.9.6-0) unstable; urgency=low * Update to 0.9.6 diff --git a/dist/deb/minimal/debian.changelog b/dist/deb/minimal/debian.changelog index 9b8a153..165a0fa 100644 --- a/dist/deb/minimal/debian.changelog +++ b/dist/deb/minimal/debian.changelog @@ -1,3 +1,10 @@ +systray-x-minimal (0.9.7-0) unstable; urgency=low + + * Update to 0.9.7 + + - Added option for new TB115 mail counting (slow with new mails enabled) + - Bugfixes + systray-x-minimal (0.9.6-0) unstable; urgency=low * Update to 0.9.6 diff --git a/dist/rpm/VERSION b/dist/rpm/VERSION index 56922d8..29f65d0 100644 --- a/dist/rpm/VERSION +++ b/dist/rpm/VERSION @@ -1,4 +1,4 @@ -VERSION=0.9.6 -BUILD_NUMBER=1004 -GIT_HASH=98823ee230826fc4e7e6986e42348f0c09de4408 +VERSION=0.9.7 +BUILD_NUMBER=1032 +GIT_HASH=311dacc37cb8101a4b17e44550a92ace0f885715 GIT_BRANCH=develop diff --git a/dist/rpm/gnome/_service b/dist/rpm/gnome/_service index 6d0931f..49d1004 100644 --- a/dist/rpm/gnome/_service +++ b/dist/rpm/gnome/_service @@ -2,8 +2,8 @@ https://github.com/Ximi1970/systray-x.git git - 0.9.6 - 0.9.6 + 0.9.7 + 0.9.7 systray-x-gnome dist/rpm/gnome/systray-x-gnome.changes dist/rpm/gnome/systray-x-gnome.spec diff --git a/dist/rpm/gnome/systray-x-gnome.changes b/dist/rpm/gnome/systray-x-gnome.changes index 9964f34..418fc76 100644 --- a/dist/rpm/gnome/systray-x-gnome.changes +++ b/dist/rpm/gnome/systray-x-gnome.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Sun Nov 12 11:12:00 UTC 2023 - Maxime Rijnders + + * Update to 0.9.7 + + - Added option for new TB115 mail counting + (slow with new mails enabled) + - Bugfixes + ------------------------------------------------------------------- Sun Oct 28 12:25:00 UTC 2023 - Maxime Rijnders diff --git a/dist/rpm/kde/_service b/dist/rpm/kde/_service index 053ca21..6a3f871 100644 --- a/dist/rpm/kde/_service +++ b/dist/rpm/kde/_service @@ -2,8 +2,8 @@ https://github.com/Ximi1970/systray-x.git git - 0.9.6 - 0.9.6 + 0.9.7 + 0.9.7 dist/rpm/kde/systray-x.changes dist/rpm/kde/systray-x.spec dist/rpm/VERSION diff --git a/dist/rpm/kde/systray-x.changes b/dist/rpm/kde/systray-x.changes index 9964f34..418fc76 100644 --- a/dist/rpm/kde/systray-x.changes +++ b/dist/rpm/kde/systray-x.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Sun Nov 12 11:12:00 UTC 2023 - Maxime Rijnders + + * Update to 0.9.7 + + - Added option for new TB115 mail counting + (slow with new mails enabled) + - Bugfixes + ------------------------------------------------------------------- Sun Oct 28 12:25:00 UTC 2023 - Maxime Rijnders diff --git a/dist/rpm/minimal/_service b/dist/rpm/minimal/_service index bdb0e0b..d9d1666 100644 --- a/dist/rpm/minimal/_service +++ b/dist/rpm/minimal/_service @@ -2,8 +2,8 @@ https://github.com/Ximi1970/systray-x.git git - 0.9.6 - 0.9.6 + 0.9.7 + 0.9.7 systray-x-minimal dist/rpm/minimal/systray-x-minimal.changes dist/rpm/minimal/systray-x-minimal.spec diff --git a/dist/rpm/minimal/systray-x-minimal.changes b/dist/rpm/minimal/systray-x-minimal.changes index 9964f34..418fc76 100644 --- a/dist/rpm/minimal/systray-x-minimal.changes +++ b/dist/rpm/minimal/systray-x-minimal.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Sun Nov 12 11:12:00 UTC 2023 - Maxime Rijnders + + * Update to 0.9.7 + + - Added option for new TB115 mail counting + (slow with new mails enabled) + - Bugfixes + ------------------------------------------------------------------- Sun Oct 28 12:25:00 UTC 2023 - Maxime Rijnders diff --git a/webext/_locales/de/messages.json b/webext/_locales/de/messages.json index 1f6311f..372fea4 100644 --- a/webext/_locales/de/messages.json +++ b/webext/_locales/de/messages.json @@ -244,6 +244,11 @@ "description": "Count new mails" }, + "count_api_count_method": { + "message": "API-Zählmethode", + "description": "API count method" + }, + "count_number_options": { "message": "Nummereigenschaften", "description": "Caption for Number options" diff --git a/webext/_locales/el/messages.json b/webext/_locales/el/messages.json index c96980a..c833f8e 100644 --- a/webext/_locales/el/messages.json +++ b/webext/_locales/el/messages.json @@ -244,6 +244,11 @@ "description": "Count new mails" }, + "count_api_count_method": { + "message": "Μέθοδος καταμέτρησης API", + "description": "API count method" + }, + "count_number_options": { "message": "Αριθμός", "description": "Caption for Number options" diff --git a/webext/_locales/en-US/messages.json b/webext/_locales/en-US/messages.json index f9c7be4..56b1eca 100644 --- a/webext/_locales/en-US/messages.json +++ b/webext/_locales/en-US/messages.json @@ -244,6 +244,11 @@ "description": "Count new mails" }, + "count_api_count_method": { + "message": "API count method", + "description": "API count method" + }, + "count_number_options": { "message": "Number", "description": "Caption for Number options" diff --git a/webext/_locales/it/messages.json b/webext/_locales/it/messages.json index 6791184..8d8f244 100644 --- a/webext/_locales/it/messages.json +++ b/webext/_locales/it/messages.json @@ -244,6 +244,11 @@ "description": "Count new mails" }, + "count_api_count_method": { + "message": "Metodo di conteggio API", + "description": "API count method" + }, + "count_number_options": { "message": "Proprietà numero", "description": "Caption for Number options" diff --git a/webext/_locales/nl/messages.json b/webext/_locales/nl/messages.json index 06269c3..681f35f 100644 --- a/webext/_locales/nl/messages.json +++ b/webext/_locales/nl/messages.json @@ -244,6 +244,11 @@ "description": "Count new mails" }, + "count_api_count_method": { + "message": "API tel methode", + "description": "API count method" + }, + "count_number_options": { "message": "Nummer opties", "description": "Caption for Number options" diff --git a/webext/_locales/pt-BR/messages.json b/webext/_locales/pt-BR/messages.json index a1f79d5..813df5b 100644 --- a/webext/_locales/pt-BR/messages.json +++ b/webext/_locales/pt-BR/messages.json @@ -244,6 +244,11 @@ "description": "Count new mails" }, + "count_api_count_method": { + "message": "Método de contagem de API", + "description": "API count method" + }, + "count_number_options": { "message": "Número", "description": "Caption for Number options" diff --git a/webext/_locales/ru/messages.json b/webext/_locales/ru/messages.json index 3befdc5..4820685 100644 --- a/webext/_locales/ru/messages.json +++ b/webext/_locales/ru/messages.json @@ -244,6 +244,11 @@ "description": "Count new mails" }, + "count_api_count_method": { + "message": "Метод подсчета API", + "description": "API count method" + }, + "count_number_options": { "message": "Настройки индикатора кол-ва", "description": "Caption for Number options" diff --git a/webext/background.js b/webext/background.js index dd5ec2a..83e8bba 100644 --- a/webext/background.js +++ b/webext/background.js @@ -1,4 +1,11 @@ var SysTrayX = { + Info: {}, + Window: {}, + Messaging: {}, + + mainWindowId: undefined, + windows: undefined, + startupState: undefined, restorePositions: false, @@ -27,7 +34,9 @@ SysTrayX.Messaging = { accounts: [], folderTree: {}, countType: "0", + showNewIndicator: "false", closeType: "1", + apiCountMethod: "false", filters: undefined, newMailCache: [], folderInfoChangeCache: [], @@ -45,7 +54,7 @@ SysTrayX.Messaging = { // Minimize on startup handled by Companion app as backup if (SysTrayX.startupState === "minimized") { - SysTrayX.Link.postSysTrayXMessage({ window: "minimized_all_startup" }); + SysTrayX.Link.postSysTrayXMessage({ window: { state : "minimized_all_startup", id: 0 } }); } // Lookout for storage changes @@ -107,12 +116,16 @@ SysTrayX.Messaging = { const getCountTypePromise = () => new Promise((res) => res(getCountType())); SysTrayX.Messaging.countType = await getCountTypePromise(); + // Get the show new indicator + const getShowNewIndicatorPromise = () => new Promise((res) => res(getShowNewIndicator())); + SysTrayX.Messaging.showNewIndicator = await getShowNewIndicatorPromise(); + // Check the filters for the accounts SysTrayX.Messaging.accountFilterCheck(); // Handle cached mail changes on startup SysTrayX.Messaging.startupDelayFinished = true; - if (SysTrayX.Info.browserInfo.majorVersion < 115) { + if (SysTrayX.Info.browserInfo.majorVersion < 115 || SysTrayX.Messaging.apiCountMethod === "false" ) { SysTrayX.Messaging.listenerNewMail(); } SysTrayX.Messaging.listenerFolderInfoChanged(); @@ -162,11 +175,11 @@ SysTrayX.Messaging = { if (ids.includes(id)) { newFilters.push(SysTrayX.Messaging.filters[i]); } else { - if (SysTrayX.Info.browserInfo.majorVersion < 115) { + if (SysTrayX.Info.browserInfo.majorVersion < 115 || SysTrayX.Messaging.apiCountMethod === "false") { if (SysTrayX.Messaging.new[id] != undefined) { delete SysTrayX.Messaging.new[id]; } - if (SysTrayX.Messaging.unread[id] != undefined) { + if (SysTrayX.Messaging.unread[id] !== undefined) { delete SysTrayX.Messaging.unread[id]; } } @@ -229,7 +242,7 @@ SysTrayX.Messaging = { }, listenerFolderInfoChanged: async function (folder, folderInfo) { - if (SysTrayX.Info.browserInfo.majorVersion < 115) { + if (SysTrayX.Info.browserInfo.majorVersion < 115 || SysTrayX.Messaging.apiCountMethod === "false") { // Cache the folder change if (folder) @@ -325,7 +338,10 @@ SysTrayX.Messaging = { sendMailCountPre115(); } } else { - sendMailCount(); + if (SysTrayX.Messaging.startupDelayFinished) + { + sendMailCount(); + } } }, @@ -349,15 +365,40 @@ SysTrayX.Messaging = { deleteFolderFromFilters(deletedFolder); }, - onCloseButton: function () { - //console.debug("Minimize all") + onNewWindow: async function (id) { + if (SysTrayX.Messaging.closeType === "2" || SysTrayX.Messaging.closeType === "4") { + // Activate the extra close button when all to tray/taskbar is selected + browser.browserAction.setTitle({title: "Force close"}); + browser.browserAction.setIcon({path: "icons/close.svg"}); + browser.browserAction.enable(); + } else { + browser.browserAction.setTitle({title: " "}); + browser.browserAction.setIcon({path: "icons/dummy.png"}); + browser.browserAction.disable(); + } - SysTrayX.Link.postSysTrayXMessage({ window: "minimized_all" }); - /* - browser.windows.update(browser.windows.WINDOW_ID_CURRENT, { - state: "minimized", - }); - */ + SysTrayX.Link.postSysTrayXMessage({ newWindow: id }); + }, + + onCloseButton: async function (id, quit) { + let state = undefined; + if (SysTrayX.Messaging.closeType === "1" || SysTrayX.Messaging.closeType === "2") { + // Minimize to tray + state = "docked"; + } else if (SysTrayX.Messaging.closeType === "3" || SysTrayX.Messaging.closeType === "4") { + // Minimize + state = "minimized"; + } + + if (state !== undefined) { + if (!quit) { + // Block the next focus change event + SysTrayX.Window.blockFocusChange = id; + } + + // Send new state to the companion + SysTrayX.Link.postSysTrayXMessage({ closeWindow: { id: id, quit: quit } }); + } }, // @@ -378,14 +419,14 @@ SysTrayX.Messaging = { browser.windowEvent.setCloseType(Number(SysTrayX.Messaging.closeType)); + browser.windowEvent.onCloseButtonClick.removeListener( + SysTrayX.Messaging.onCloseButton + ); + if (SysTrayX.Messaging.closeType !== "0") { browser.windowEvent.onCloseButtonClick.addListener( SysTrayX.Messaging.onCloseButton ); - } else { - browser.windowEvent.onCloseButtonClick.removeListener( - SysTrayX.Messaging.onCloseButton - ); } } @@ -396,6 +437,13 @@ SysTrayX.Messaging = { sendMailCount(); } + if ("showNewIndicator" in changes && changes["showNewIndicator"].newValue) { + SysTrayX.Messaging.showNewIndicator = changes["showNewIndicator"].newValue; + + sendMailCountPre115(); + sendMailCount(); + } + if ("addonprefchanged" in changes && changes["addonprefchanged"].newValue) { // // Send new preferences to the app @@ -575,6 +623,7 @@ SysTrayX.Messaging = { "showNewIndicator", "countType", "startupDelay", + "apiCountMethod", "numberColor", "numberSize", "numberAlignment", @@ -611,6 +660,7 @@ SysTrayX.Messaging = { const showNewIndicator = result.showNewIndicator || "false"; const countType = result.countType || "0"; const startupDelay = result.startupDelay || "5"; + const apiCountMethod = result.apiCountMethod || "false"; let numberColor = result.numberColor || "#000000"; const numberSize = result.numberSize || "10"; const numberAlignment = result.numberAlignment || "4"; @@ -648,6 +698,7 @@ SysTrayX.Messaging = { showNewIndicator, countType, startupDelay, + apiCountMethod, numberColor, numberSize, numberAlignment, @@ -665,7 +716,7 @@ SysTrayX.Messaging = { // Send startup state after the prefs // so the hide is handled conform the prefs if (SysTrayX.startupState === "minimized") { - SysTrayX.Link.postSysTrayXMessage({ window: "minimized_all" }); + SysTrayX.Link.postSysTrayXMessage({ window: { state: "minimized_all", id: 0 } } ); //SysTrayX.Link.postSysTrayXMessage({ window: SysTrayX.startupState }); } @@ -849,6 +900,14 @@ SysTrayX.Link = { }); } + const apiCountMethod = response["preferences"].apiCountMethod; + if (apiCountMethod !== undefined) { + await storage().set({ + apiCountMethod: apiCountMethod, + }); + SysTrayX.Messaging.apiCountMethod = apiCountMethod; + } + const numberColor = response["preferences"].numberColor; if (numberColor) { await storage().set({ @@ -930,9 +989,21 @@ SysTrayX.Link = { }; SysTrayX.Window = { + blockFocusChange: 0, + focusChanged: function (windowId) { browser.windows.getCurrent().then((win) => { - SysTrayX.Link.postSysTrayXMessage({ window: win.state }); + + //console.debug("focusChanged Id: " + win.id); + //console.debug("focusChanged state: " + win.state); + //console.debug("focusChanged block: " + SysTrayX.Window.blockFocusChange); + + if( win.id !== SysTrayX.Window.blockFocusChange) { + SysTrayX.Link.postSysTrayXMessage({ window: { state: win.state, id: win.id } } ); + } else { + // Reset block + SysTrayX.Window.blockFocusChange = 0; + } }); }, @@ -941,7 +1012,7 @@ SysTrayX.Window = { //console.debug("Folder changed tab: " + JSON.stringify(tab)); //console.debug("Folder changed displayedFolder: " + JSON.stringify(displayedFolder)); - if (SysTrayX.Info.browserInfo.majorVersion < 115) { + if (SysTrayX.Info.browserInfo.majorVersion < 115 || SysTrayX.Messaging.apiCountMethod === "false") { const oldDisplayedFolder = SysTrayX.Messaging.displayedFolder; if (oldDisplayedFolder !== undefined) { if ( @@ -970,6 +1041,20 @@ SysTrayX.Window = { }; async function start() { + // Setup the link first + SysTrayX.Link.init(); + + // Force close a window using a toolbar button + browser.browserAction.disable(); + + browser.browserAction.onClicked.addListener(async () => { + const window = await browser.windows.getCurrent(); + browser.windowEvent.forceClose(window.id); + + // Send new state to the companion + SysTrayX.Link.postSysTrayXMessage({ closeWindow: { id: window.id, quit: true } }); + }); + // Set platform SysTrayX.Info.platformInfo = await browser.runtime .getPlatformInfo() @@ -989,8 +1074,12 @@ async function start() { SysTrayX.Info.displayInfo(); + // Get the API count method preference + const apiCountMethod = await getApiCountMethod(); + SysTrayX.Messaging.apiCountMethod = apiCountMethod; + // Try to catch the mails - if (SysTrayX.Info.browserInfo.majorVersion < 115) { + if (SysTrayX.Info.browserInfo.majorVersion < 115 || SysTrayX.Messaging.apiCountMethod === "false") { // Catch the new incomming mail browser.messages.onNewMailReceived.addListener( SysTrayX.Messaging.listenerNewMail @@ -1021,12 +1110,31 @@ async function start() { SysTrayX.startupWindowPositions = await getStartupWindowPositions(); } - // Get the close type + // Get main window id + const window = await browser.windows.getCurrent(); + SysTrayX.mainWindowId = window.id; + + //console.debug("Main window ID: " + SysTrayX.mainWindowId); + + // Get all windows + const windows = await browser.windows.getAll(); + SysTrayX.windows = windows; + + //console.debug("All window IDs: " + JSON.stringify(windows.map((win) => win.id))); + //console.debug("Window: " + JSON.stringify(windows)); + + // Set the close type SysTrayX.Messaging.closeType = await getCloseType(); browser.windowEvent.setCloseType(Number(SysTrayX.Messaging.closeType)); + // Set the main window id + browser.windowEvent.setMainWindowId(Number(SysTrayX.mainWindowId)); + // Intercept close button? if (SysTrayX.Messaging.closeType !== "0") { + browser.windowEvent.onNewWindow.addListener( + SysTrayX.Messaging.onNewWindow + ); browser.windowEvent.onCloseButtonClick.addListener( SysTrayX.Messaging.onCloseButton ); @@ -1060,9 +1168,6 @@ async function start() { const getIconPromise = () => new Promise((res) => res(getIcon())); await getIconPromise(); - // Setup the link first - SysTrayX.Link.init(); - // Main start SysTrayX.Messaging.init(); } diff --git a/webext/icons/close.svg b/webext/icons/close.svg new file mode 100644 index 0000000..1b7056c --- /dev/null +++ b/webext/icons/close.svg @@ -0,0 +1,17 @@ + + + + + + diff --git a/webext/icons/dummy.png b/webext/icons/dummy.png new file mode 100644 index 0000000..647fbf7 Binary files /dev/null and b/webext/icons/dummy.png differ diff --git a/webext/js/defaults.js b/webext/js/defaults.js index 087069d..f030c8e 100644 --- a/webext/js/defaults.js +++ b/webext/js/defaults.js @@ -6,6 +6,22 @@ function storage() { return browser.storage.local; } +// +// Get API count method preference +// +async function getApiCountMethod() { + function resolve(result) { + const apiCountMethod = result.apiCountMethod || "false"; + return apiCountMethod; + } + + function reject() { + return "false"; + } + + return await storage().get("apiCountMethod").then(resolve, reject); +} + // // Get window startup state // @@ -219,7 +235,7 @@ async function getFilters() { filters = []; for (const account of SysTrayX.Messaging.accounts) { const inbox = account.folders.filter( - (folder) => folder.type == "inbox" + (folder) => folder.type === "inbox" ); if (inbox.length > 0) { @@ -259,12 +275,27 @@ async function getCountType() { } function reject() { - return undefined; + return "0"; } return await storage().get("countType").then(resolve, reject); } +// +// Get show new indicator +// +async function getShowNewIndicator() { + function resolve(result) { + return result.showNewIndicator || "false"; + } + + function reject() { + return "false"; + } + + return await storage().get("showNewIndicator").then(resolve, reject); +} + // // Get start app parameters // @@ -416,7 +447,7 @@ const collectUnreadMail = async () => { // Count and send the unread and new mails const sendMailCountPre115 = () => { - if (SysTrayX.Info.browserInfo.majorVersion < 115) { + if (SysTrayX.Info.browserInfo.majorVersion < 115 || SysTrayX.Messaging.apiCountMethod === "false") { // Collect the unread mail collectUnreadMail(); @@ -453,44 +484,79 @@ const sendMailCountPre115 = () => { // Count and send the unread and new mails (>TB115) const sendMailCount = async () => { - if (SysTrayX.Info.browserInfo.majorVersion >= 115) { + if (SysTrayX.Info.browserInfo.majorVersion >= 115 && SysTrayX.Messaging.apiCountMethod === "true") { // New only works for >=TB106 let unreadCount = 0; let newCount = 0; - for (const filter of SysTrayX.Messaging.filters) { - for (const path of filter.folders) { - const folder = { - accountId: filter.accountId, - path: path, - }; + if( SysTrayX.Messaging.countType === "1" || SysTrayX.Messaging.showNewIndicator === "true" ) { - async function* listMessages(folder) { - let page = await messenger.messages.list(folder); - for (let message of page.messages) { - yield message; - } - - while (page.id) { - page = await messenger.messages.continueList(page.id); + // Get both unread and new message count + + for (const filter of SysTrayX.Messaging.filters) { + for (const path of filter.folders) { + const folder = { + accountId: filter.accountId, + path: path, + }; + + async function* listMessages(folder) { + let page = await messenger.messages.list(folder); for (let message of page.messages) { yield message; } + + while (page.id) { + page = await messenger.messages.continueList(page.id); + for (let message of page.messages) { + yield message; + } + } + } + + let messages = listMessages(folder); + for await (let message of messages) { + if( message.new ) + { + newCount = newCount + 1; + } + + if( !message.read ) + { + unreadCount = unreadCount + 1; + } } } - - let messages = listMessages(folder); - for await (let message of messages) { - if( message.new ) - { - newCount = newCount + 1; + } + } else { + + // Only unread count + + for (const filter of SysTrayX.Messaging.filters) { + for (const path of filter.folders) { + const folder = { + accountId: filter.accountId, + path: path, + }; + + let mailFolderInfo = {}; + try { + mailFolderInfo = await browser.folders.getFolderInfo(folder); + } catch (err) { + //console.debug("Filter error: " + err); + //console.debug("Filter error: " + JSON.stringify(folder)); + + // Get all accounts + SysTrayX.Messaging.accounts = await browser.accounts.list(false); + + // Check the filters for the accounts + SysTrayX.Messaging.accountFilterCheck(); } - if( !message.read ) - { - unreadCount = unreadCount + 1; + if (mailFolderInfo.unreadMessageCount !== undefined) { + unreadCount = unreadCount + mailFolderInfo.unreadMessageCount; } } } diff --git a/webext/js/options_accounts.js b/webext/js/options_accounts.js index c1be762..818fa48 100644 --- a/webext/js/options_accounts.js +++ b/webext/js/options_accounts.js @@ -150,7 +150,7 @@ SysTrayX.Accounts = { JSON.stringify({ accountName: element.accountName, accountId: element.accountId, - type: element.type != undefined ? element.type : "", + type: element.type !== undefined ? element.type : "", path: element.path, name: element.originalName ? element.originalName @@ -210,7 +210,7 @@ SysTrayX.Accounts = { ':scope > input[type="checkbox"]' ); - if (mainCb && mainCb != this) { + if (mainCb && mainCb !== this) { mainCb.checked = this.checked; const mainCbChildren = mainCb.parentNode.querySelectorAll( diff --git a/webext/js/windowEvent.js b/webext/js/windowEvent.js index f58d6b3..2293e1c 100644 --- a/webext/js/windowEvent.js +++ b/webext/js/windowEvent.js @@ -1,206 +1,340 @@ -// This is the important part. It implements the functions and events defined in schema.json. -// The variable must have the same name you've been using so far, "myapi" in this case. -var windowEvent = class extends ExtensionCommon.ExtensionAPI { - getAPI(context) { - console.log("windowEvent API started"); +/* eslint-disable object-shorthand */ - // To be notified of the extension going away, call callOnClose with any object that has a - // close function, such as this one. - context.callOnClose(this); +"use strict"; - return { - // Again, this key must have the same name. - windowEvent: { - setCloseType: async function (type) { - windowListener.setCloseType(type); - }, +// Using a closure to not leak anything but the API to the outside world. +(function (exports) { - // An event. Most of this is boilerplate you don't need to worry about, just copy it. - onCloseButtonClick: new ExtensionCommon.EventManager({ - context, - name: "windowEvent.onCloseButtonClick", - // In this function we add listeners for any events we want to listen to, and return a - // function that removes those listeners. To have the event fire in your extension, - // call fire.async. - register(fire) { - function callback(event) { - return fire.async(); - } + // Get various parts of the WebExtension framework that we need. + var { ExtensionCommon } = ChromeUtils.import("resource://gre/modules/ExtensionCommon.jsm"); - windowListener.addOnCloseButton(callback); - return function () { - windowListener.removeOnCloseButton(callback); - }; - }, - }).api(), - }, - }; - } + // You probably already know what this does. + var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); - close() { - // This function is called if the extension is disabled or removed, or Thunderbird closes. - // We registered it with callOnClose, above. - console.log("windowEvent API closed"); - } -}; + // A helpful class for listening to windows opening and closing. + var { ExtensionSupport } = ChromeUtils.import("resource:///modules/ExtensionSupport.jsm"); -// A helpful class for listening to windows opening and closing. -// (This file had a lowercase E in Thunderbird 65 and earlier.) -var { ExtensionSupport } = ChromeUtils.import( - "resource:///modules/ExtensionSupport.jsm" -); + /** + * This object is just what we're using to listen for toolbar clicks. The implementation + * isn't what this example is about, but you might be interested as it's a common pattern. + * We count the number of callbacks waiting for events so that we're only listening if we + * need to be. + * + * An EventEmitter has the following basic functions: + * + * EventEmitter.on(emitterName, callback) + * Registers a callback for a custom emitter. + * + * EventEmitter.off(emitterName, callback) + * Unregisters a callback for a custom emitter. + * + * EventEmitter.emit(emitterName) + * Emit a custom emitter, all provided parameters will be forwarded to the registered callbacks. + */ -// This object is just what we're using to listen for toolbar clicks. The implementation isn't -// what this example is about, but you might be interested as it's a common pattern. We count the -// number of callbacks waiting for events so that we're only listening if we need to be. -var windowListener = new (class extends ExtensionCommon.EventEmitter { - constructor() { - super(); - this.callbackOnCloseButtonCount = 0; - this.callbackOnLoadWindowCount = 0; + let windowListener; - this.MESSAGE_CLOSE_TYPE_DEFAULT = 0; - this.MESSAGE_CLOSE_TYPE_MIN_MAIN_TRAY_CLOSE_CHILDREN = 1; - this.MESSAGE_CLOSE_TYPE_MIN_ALL_TRAY = 2; - this.MESSAGE_CLOSE_TYPE_MIN_MAIN_CLOSE_CHILDREN = 3; - this.MESSAGE_CLOSE_TYPE_MIN_ALL = 4; + class WindowListener extends ExtensionCommon.EventEmitter { + constructor(extension) { + super(); + this.extension = extension; + this.onNewWindowCallbackCount = 0; + this.onCloseButtonClickCallbackCount = 0; - this.closeType = this.MESSAGE_CLOSE_TYPE_MIN_MAIN_CLOSE_CHILDREN; - } - - setCloseType(closeType) { - if (closeType === 0) { + this.MESSAGE_CLOSE_TYPE_DEFAULT = 0; + this.MESSAGE_CLOSE_TYPE_MIN_MAIN_TRAY_CLOSE_CHILDREN = 1; + this.MESSAGE_CLOSE_TYPE_MIN_ALL_TRAY = 2; + this.MESSAGE_CLOSE_TYPE_MIN_MAIN_CLOSE_CHILDREN = 3; + this.MESSAGE_CLOSE_TYPE_MIN_ALL = 4; + this.closeType = this.MESSAGE_CLOSE_TYPE_DEFAULT; - } else if (closeType === 1) { - this.closeType = this.MESSAGE_CLOSE_TYPE_MIN_MAIN_TRAY_CLOSE_CHILDREN; - } else if (closeType === 2) { - this.closeType = this.MESSAGE_CLOSE_TYPE_MIN_ALL_TRAY; - } else if (closeType === 3) { - this.closeType = this.MESSAGE_CLOSE_TYPE_MIN_MAIN_CLOSE_CHILDREN; - } else if (closeType === 4) { - this.closeType = this.MESSAGE_CLOSE_TYPE_MIN_ALL; - } else console.log("Unknown close type: " + closeType); - } + this.mainWindowId = 0; - addOnCloseButton(callback) { - if (this.callbackOnCloseButtonCount == 0) { - this.on("close-clicked", callback); - this.callbackOnCloseButtonCount++; - - ExtensionSupport.registerWindowListener("closeButtonListener", { - chromeURLs: [ - "chrome://messenger/content/messenger.xhtml", - "chrome://messenger/content/messenger.xul", - ], - onLoadWindow: function (window) { - windowListener.callbackOnLoadWindowCount++; - if ( - windowListener.callbackOnLoadWindowCount === 1 || - windowListener.closeType === - windowListener.MESSAGE_CLOSE_TYPE_MIN_ALL || - windowListener.closeType === - windowListener.MESSAGE_CLOSE_TYPE_MIN_ALL_TRAY - ) { - window.addEventListener( - "close", - windowListener.onCloseButton, - true - ); - windowListener.hijackTitlebarCloseButton(window); - - windowListener.oldClose = window.close; - window.close = () => windowListener.onCloseButton(null); - - console.log("Close listener added"); - } - }, - }); + this.activeWindows = {}; } - } - removeOnCloseButton(callback) { - if (this.callbackOnCloseButtonCount == 1) { - this.off("close-clicked", callback); - this.callbackOnCloseButtonCount--; + get listenerIdNewWindow() { + return `window_event_listener_new_window_${this.extension.uuid}_${this.extension.instanceId}`; + } - for (let window of ExtensionSupport.openWindows) { - if ( - [ + get listenerIdCloseButton() { + return `window_event_listener_close_button_${this.extension.uuid}_${this.extension.instanceId}`; + } + + setCloseType(closeType) { + if (closeType === 0) { + this.closeType = this.MESSAGE_CLOSE_TYPE_DEFAULT; + } else if (closeType === 1) { + this.closeType = this.MESSAGE_CLOSE_TYPE_MIN_MAIN_TRAY_CLOSE_CHILDREN; + } else if (closeType === 2) { + this.closeType = this.MESSAGE_CLOSE_TYPE_MIN_ALL_TRAY; + } else if (closeType === 3) { + this.closeType = this.MESSAGE_CLOSE_TYPE_MIN_MAIN_CLOSE_CHILDREN; + } else if (closeType === 4) { + this.closeType = this.MESSAGE_CLOSE_TYPE_MIN_ALL; + } else console.log("Unknown close type: " + closeType); + } + + setMainWindowId(id) { + this.mainWindowId = id; + } + + forceClose(id) { + if (this.activeWindows[id] !== undefined) { + this.activeWindows[id].window.close = this.activeWindows[id].close; + this.activeWindows[id].window.close(); + } + } + + addOnNewWindow(callback, context) { + // Registering the callback for "new-window". + this.on("new-window", callback); + this.onNewWindowCallbackCount++; + + if (this.onNewWindowCallbackCount === 1) { + ExtensionSupport.registerWindowListener(this.listenerIdNewWindow, { + context, + chromeURLs: [ "chrome://messenger/content/messenger.xhtml", "chrome://messenger/content/messenger.xul", - ].includes(window.location.href) - ) { - window.removeEventListener( - "close", - windowListener.onCloseButton, - true - ); - window.close = windowListener.oldClose; + ], + onLoadWindow: function (window) { + // Get current window id + const id = context.extension.windowManager.getWrapper(window).id; - console.log("Close listener removed"); + windowListener.emit("new-window", id); + + console.log("New window added: " + id); + } + }); + } + } + + removeOnNewWindow(callback, context) { + // Un-Registering the callback for "new-window". + this.off("new-window", callback); + this.onNewWindowCallbackCount--; + + if (this.onNewWindowCallbackCount === 0) { + for (let window of ExtensionSupport.openWindows) { + if ([ + "chrome://messenger/content/messenger.xhtml", + "chrome://messenger/content/messenger.xul", + ].includes(window.location.href)) { + // Get current window id + const id = context.extension.windowManager.getWrapper(window).id; + + console.log("New window removed: " + id); + } } + ExtensionSupport.unregisterWindowListener( this.listenerIdNewWindow ); } - ExtensionSupport.unregisterWindowListener("closeButtonListener"); } - } + + addOnCloseButtonClick(callback, context) { + // Registering the callback for "close-clicked". + this.on( "close-clicked", callback ); + this.onCloseButtonClickCallbackCount++; - onCloseButton(event) { - if (event) event.preventDefault(); - windowListener.emit("close-clicked"); - return true; - } + if (this.onCloseButtonClickCallbackCount === 1) { + ExtensionSupport.registerWindowListener(this.listenerIdCloseButton, { + context, + chromeURLs: [ + "chrome://messenger/content/messenger.xhtml", + "chrome://messenger/content/messenger.xul", + ], + onLoadWindow: function ( window ) { + // Get current window id + const id = context.extension.windowManager.getWrapper(window).id - hijackTitlebarCloseButton(window) { - if ( - windowListener.replaceCommand(window, "titlebar-close", function () { - return windowListener.onCloseButton(null); - }) - ) { - console.log("replaced command= " + "titlebar-close"); - } - } + if (id === windowListener.mainWindowId || + windowListener.closeType === windowListener.MESSAGE_CLOSE_TYPE_MIN_ALL_TRAY || + windowListener.closeType === windowListener.MESSAGE_CLOSE_TYPE_MIN_ALL) { - replaceCommand(window, eltId, gotHidden) { - let elt = window.document.getElementById(eltId); - if (!elt) { - console.log("Element '" + eltId + "' not found. Command not replaced."); - return false; + function onCloseButton(event) { + if ( event ) event.preventDefault(); + windowListener.emit("close-clicked", id, false); +// console.log("Close clicked: " + event); +// console.log("Close clicked: " + id); + return true; + } + + // Store the window data + windowListener.activeWindows[id] = { + window, + close : window.close, + listener: onCloseButton + }; + + // Intercept the close event (triggered when clicking the close button) + window.addEventListener( + "close", + onCloseButton, + true + ); + + // Pre TB115 close menu, now same as close button + window.close = () => onCloseButton(null); + + console.log("Close listener added for: " + id); + } else { + + function onCloseButton2(event) { + console.log("Real Close clicked: " + id); + + windowListener.emit("close-clicked", id, true); + + window.close = windowListener.activeWindows[id].close; + window.close(); + return false; + } + + // Store the window data + windowListener.activeWindows[id] = { + window, + close : window.close, + listener: onCloseButton2 + }; + + // Intercept the close event (triggered when clicking the close button) + window.addEventListener( + "close", + onCloseButton2, + true + ); + + // Pre TB115 close menu, now same as close button + window.close = () => onCloseButton2(null); + } + }, + }); + } } - let prevent = null; - if (elt.command) { - prevent = { - event: "click", - func: function (e) { - e.preventDefault(); + removeOnCloseButtonClick(callback, context) { + // Un-Registering the callback for "close-clicked". + this.off( "close-clicked", callback ); + this.onCloseButtonClickCallbackCount--; + + if (this.onCloseButtonClickCallbackCount === 0) { + for (let window of ExtensionSupport.openWindows) { + if ([ + "chrome://messenger/content/messenger.xhtml", + "chrome://messenger/content/messenger.xul", + ].includes(window.location.href)) { + // Get current window id + const id = context.extension.windowManager.getWrapper(window).id + + if (id === windowListener.mainWindowId || + windowListener.closeType === windowListener.MESSAGE_CLOSE_TYPE_MIN_ALL_TRAY || + windowListener.closeType === windowListener.MESSAGE_CLOSE_TYPE_MIN_ALL) { + + // Release the close event (triggered when clicking the close button) + window.removeEventListener( + "close", + windowListener.activeWindows[id].listener, + true + ); + + window.close = windowListener.activeWindows[id].close; + + // Clean the storage + delete windowListener.activeWindows[id]; + + console.log("Close listener removed for: " + id); + } + } + } + ExtensionSupport.unregisterWindowListener(this.listenerIdCloseButton); + } + } + }; + + // This is the important part. It implements the functions and events defined + // in the schema.json. The name must match what you've been using so far, + // "windowEvent" in this case. + class windowEvent extends ExtensionCommon.ExtensionAPI { + // An alternative to defining a constructor here, is to use the onStartup + // event. However, this causes the API to be instantiated directly after the + // add-on has been loaded, not when the API is first used. Depends on what is + // desired. + constructor(extension) { + super(extension); + windowListener = new WindowListener(extension); + } + + getAPI(context) { + console.log("windowEvent API started"); + + return { + // This key must match the class name. + windowEvent: { + setCloseType: async function (type) { + windowListener.setCloseType(type); + }, + + setMainWindowId: async function (id) { + windowListener.setMainWindowId(id); + }, + + forceClose: async function (id) { + windowListener.forceClose(id); + }, + + // An event. Most of this is boilerplate you don't need to worry about, just copy it. + onNewWindow: new ExtensionCommon.EventManager({ + context, + name: "windowEvent.onNewWindow", + // In this function we add listeners for any events we want to listen to, and return a + // function that removes those listeners. To have the event fire in your extension, + // call fire.async. + register(fire) { + function callback(event, id) { + return fire.async(id); + } + + windowListener.addOnNewWindow(callback,context); + return function () { + windowListener.removeOnNewWindow(callback,context); + }; + }, + }).api(), + + // An event. Most of this is boilerplate you don't need to worry about, just copy it. + onCloseButtonClick: new ExtensionCommon.EventManager({ + context, + name: "windowEvent.onCloseButtonClick", + // In this function we add listeners for any events we want to listen to, and return a + // function that removes those listeners. To have the event fire in your extension, + // call fire.async. + register(fire) { + function callback(event, id, quit) { + return fire.async(id, quit); + } + + windowListener.addOnCloseButtonClick(callback,context); + return function () { + windowListener.removeOnCloseButtonClick(callback,context); + }; + }, + }).api(), }, }; - } else if (elt.getAttribute("oncommand")) { - prevent = { - event: "command", - func: function (e) { - e.stopPropagation(); - }, - }; - } else { - console.warn("Could not replace oncommand on " + eltId); - return false; } - let callback = function (event) { - if (event.target.id === eltId) { - console.debug(prevent.event + " on " + eltId); - if (gotHidden()) prevent.func(event); + onShutdown(isAppShutdown) { + // This function is called if the extension is disabled or removed, or Thunderbird closes. + // We usually do not have to do any cleanup, if Thunderbird is shutting down entirely + if (isAppShutdown) { + return; } - }; - /* We put listeners on the "titlebar" parent node, because: - - we can hardly short-circuit command/oncommand (probably because they are - registered first) - - we'd have otherwise to alter "oncommand"/"command" attribute and use - Function(), which do not pass review nowadays. */ - elt.parentNode.addEventListener(prevent.event, callback, true); + console.log("windowEvent API closed"); + } + }; - return true; - } -})(); + // Export the api by assigning in to the exports parameter of the anonymous closure + // function, which is the global this. + exports.windowEvent = windowEvent; + +})(this) diff --git a/webext/manifest.json b/webext/manifest.json index 62fe2eb..e0afec7 100644 --- a/webext/manifest.json +++ b/webext/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "__MSG_extension_name__", "description": "__MSG_extension_description__", - "version": "0.9.6", + "version": "0.9.7", "author": "Maxime Rijnders", "homepage_url": "https://github.com/Ximi1970/systray-x", @@ -22,6 +22,12 @@ "permissions": ["accountsRead", "messagesRead", "storage", "nativeMessaging"], + "browser_action": { + "default_title": " ", + "default_icon": "icons/dummy.png", + "allowed_spaces": ["mail", "addressbook", "calendar", "tasks", "chat", "settings", "default" ] + }, + "background": { "page": "background.html" }, diff --git a/webext/options.html b/webext/options.html index 39ef51b..03eb0cd 100644 --- a/webext/options.html +++ b/webext/options.html @@ -419,6 +419,15 @@ +
+
+ + +
+
+
__MSG_count_number_options__ diff --git a/webext/options.js b/webext/options.js index 459ca19..f251cc1 100644 --- a/webext/options.js +++ b/webext/options.js @@ -222,6 +222,14 @@ SysTrayX.SaveOptions = { startupDelay: startupDelay, }); + // + // Save API count method state + // + const apiCountMethod = document.querySelector('input[name="apiCountMethod"]').checked; + await storage().set({ + apiCountMethod: `${apiCountMethod}`, + }); + // // Save number color // @@ -496,6 +504,16 @@ SysTrayX.RestoreOptions = { SysTrayX.RestoreOptions.ontartupDelayError ); + // + // Restore API count method state + // + await storage() + .get("apiCountMethod") + .then( + SysTrayX.RestoreOptions.setApiCountMethod, + SysTrayX.RestoreOptions.onApiCountMethodError + ); + // // Restore number color // @@ -924,6 +942,20 @@ SysTrayX.RestoreOptions = { console.log(`StartupDelay Error: ${error}`); }, + // + // Restore API count method state callbacks + // + setApiCountMethod: function (result) { + const apiCountMethod = result.apiCountMethod || "false"; + + const checkbox = document.querySelector(`input[name="apiCountMethod"]`); + checkbox.checked = apiCountMethod === "true"; + }, + + onApiCountMethodError: function (error) { + console.log(`ApiCountMethod Error: ${error}`); + }, + // // Restore number color // @@ -1278,6 +1310,11 @@ SysTrayX.StorageChanged = { startupDelay: changes[item].newValue, }); } + if (item === "apiCountMethod") { + SysTrayX.RestoreOptions.setApiCountMethod({ + apiCountMethod: changes[item].newValue, + }); + } if (item === "numberColor") { SysTrayX.RestoreOptions.setNumberColor({ numberColor: changes[item].newValue, @@ -1401,6 +1438,10 @@ async function start() { document.getElementById("kdeintegration").style.display = "none"; } + if (SysTrayX.Info.browserInfo.majorVersion < 115) { + document.getElementById("apicountmethod").style.display = "none"; + } + // Setup account tree const accountsInitPromise = () => new Promise((res) => res(SysTrayX.Accounts.init())); diff --git a/webext/schema_windowEvent.json b/webext/schema_windowEvent.json index 6a5495f..a14ff27 100644 --- a/webext/schema_windowEvent.json +++ b/webext/schema_windowEvent.json @@ -15,13 +15,43 @@ "maximum": 4 } ] + }, + { + "name": "setMainWindowId", + "type": "function", + "description": "Set the main window id.", + "async": true, + "parameters": [ + { + "type": "integer", + "name": "type" + } + ] + }, + { + "name": "forceClose", + "type": "function", + "description": "Really close the window.", + "async": true, + "parameters": [ + { + "type": "integer", + "name": "type" + } + ] } ], "events": [ + { + "name": "onNewWindow", + "type": "function", + "description": "Fires when the user opens a new window.", + "parameters": [] + }, { "name": "onCloseButtonClick", "type": "function", - "description": "Fires when the user clicks on the close button of the main window.", + "description": "Fires when the user clicks on the close button of a window.", "parameters": [] } ]