Merge branch 'feature-window-ctrl' into develop

This commit is contained in:
Ximi1970
2020-03-02 22:51:19 +01:00
46 changed files with 2474 additions and 919 deletions

4
.gitignore vendored
View File

@@ -1,2 +1,2 @@
*.xpi
/*.xpi
/SysTray-X

View File

@@ -7,7 +7,8 @@ The add-on and system tray application can do:
- custom new mail icon
- display number of unread mails
- show / hide Thunderbird (minimize)
- to be implemented: remove from task bar when minimized
- minimizing hides to tray
- minimize on startup
- to be implemented: start a new mail
- to be implemented: open the last used account

View File

@@ -1,3 +1,116 @@
#<script>
Windows
=========================================
c# remove 3rd party application from taskbar
(first answer)
https://stackoverflow.com/questions/10514882/c-sharp-remove-3rd-party-application-from-taskbar
Close window
https://docs.microsoft.com/en-us/windows/win32/learnwin32/closing-the-window
Block close button
https://devblogs.microsoft.com/oldnewthing/20100604-00/?p=13803
Get processes
(EnumProcesses function)
https://www.qtcentre.org/threads/46145-Get-All-Running-Process-Win32
Get (Pid) and PPid
https://stackoverflow.com/questions/185254/how-can-a-win32-process-get-the-pid-of-its-parent
https://stackoverflow.com/questions/18401572/c-how-to-fetch-parent-process-id
https://www.codeproject.com/Articles/9893/Get-Parent-Process-PID
X11
==========================================
Get processes (parent pid, pid and arguments)
ps -eo ppid,pid,args
qint64 QCoreApplication::applicationPid() to get systrayx pid -> parent pid -> tb window.
ps -p [PID] -o ppid
Bash
xwininfo -tree -root
How to get the list of open windows from xserver
https://stackoverflow.com/questions/252906/how-to-get-the-list-of-open-windows-from-xserver
-> XQueryTree Xlib
https://tronche.com/gui/x/xlib/window-information/XQueryTree.html
https://stackoverflow.com/questions/11594184/getting-a-list-of-window-wids-in-qt
How to detect window state in linux?
https://stackoverflow.com/questions/37003959/how-to-detect-window-state-in-linux
Taskbar hide
https://stackoverflow.com/questions/41622735/hide-window-from-linux-taskbar
minimize fullscreen Xlib OpenGL Window
https://stackoverflow.com/questions/6381098/minimize-fullscreen-xlib-opengl-window
Close windows
https://stackoverflow.com/questions/41202622/xlib-soft-closing-a-window
Intercept close event X11
https://stackoverflow.com/questions/1157364/intercept-wm-delete-window-on-x11
Allowed actions
https://stackoverflow.com/questions/28495586/x11-how-to-set-net-wm-allowed-actions
Qt X11
https://doc.qt.io/qt-5/qx11info.html
Obesolete X11 container qt4
https://stackoverflow.com/questions/39515384/qx11embedcontainer-alternative-in-qt5
Example container
https://stackoverflow.com/questions/1102658/qx11embedwidget-and-qx11embedcontainer
==========================================
Arguments for <script>
https://stackoverflow.com/questions/5292372/how-to-pass-parameters-to-a-script-tag

2
app/.gitignore vendored
View File

@@ -1 +1 @@
build-*
build*

View File

@@ -31,7 +31,10 @@ CONFIG += c++11
unix:!macx: {
QMAKE_CFLAGS += $(RPM_OPT_FLAGS)
QMAKE_CXXFLAGS += $(RPM_OPT_FLAGS)
# QMAKE_LFLAGS += -lX11 -static-libgcc -static-libstdc++
QMAKE_LFLAGS += $(RPM_OPT_FLAGS)
# QMAKE_LFLAGS += -static-libgcc -static-libstdc++
LIBS += -lX11
}
win32: {
# QMAKE_LFLAGS += -static -lwinpthread -static-libgcc -static-libstdc++ $$(QMAKE_LFLAGS_WINDOWS)
@@ -40,29 +43,8 @@ win32: {
# Windows host (not used in cross compiling with mingw on Linux)
#
contains(QMAKE_HOST.os, Windows): {
contains(QMAKE_HOST.version, 192): {
#
# Windows 10 Universal CRT
#
UCRT_INCLUDE = "C:/Program Files (x86)/Windows Kits/10/include/10.0.10240.0/ucrt"
UCRT_LIBS = "C:/Program Files (x86)/Windows Kits/10/Lib/10.0.10240.0/ucrt"
INCLUDEPATH += $$UCRT_INCLUDE
contains(QMAKE_TARGET.arch, x86_64) {
CONFIG(debug, debug|release) {
LIBS += $$UCRT_LIBS"/x64/ucrtd.lib"
} else {
LIBS += $$UCRT_LIBS"/x64/ucrt.lib"
}
} else {
CONFIG(debug, debug|release) {
LIBS += $$UCRT_LIBS"/x86/ucrtd.lib"
} else {
LIBS += $$UCRT_LIBS"/x86/ucrt.lib"
}
}
}
LIBS += User32.lib
LIBS += Comctl32.lib
}
}
unix:macx: {
@@ -136,7 +118,7 @@ win32: {
} else {
JSON_EXE_PATH = $$system(powershell -Command "('$$shell_path($${OUT_PWD}/release/$${TARGET}.exe)').replace('\\','\\\\')")
QMAKE_POST_LINK = $$[QT_INSTALL_BINS]\windeployqt.exe "$$shell_path($${OUT_PWD}/release/$${TARGET}.exe)"
QMAKE_POST_LINK = $$[QT_INSTALL_BINS]\windeployqt.exe "$$shell_path($${OUT_PWD}/release/$${TARGET}.exe)" &
QMAKE_POST_LINK += powershell -Command \"(Get-Content $$shell_path($${_PRO_FILE_PWD_}/../config/win32/SysTray_X.json.template) ).replace(\'SYSTRAY_X_PATH\',\'$$JSON_EXE_PATH\') | Set-Content $$shell_path($${_PRO_FILE_PWD_}/../config/win32/SysTray_X.json)\" &
}
@@ -158,7 +140,8 @@ SOURCES += \
systrayx.cpp \
debugwidget.cpp \
preferencesdialog.cpp \
preferences.cpp
preferences.cpp \
windowctrl.cpp
unix: {
SOURCES += \
windowctrl-unix.cpp

View File

@@ -2,5 +2,12 @@
<qresource prefix="/">
<file>files/icons/SysTray-X.png</file>
<file>files/icons/blank-icon.png</file>
<file>files/icons/Thunderbird.png</file>
<file>files/icons/document-new.png</file>
<file>files/icons/gtk-apply.png</file>
<file>files/icons/gtk-edit.png</file>
<file>files/icons/gtk-preferences.png</file>
<file>files/icons/window-close.png</file>
<file>files/icons/window-restore.png</file>
</qresource>
</RCC>

View File

@@ -6,6 +6,10 @@
*/
#include "preferences.h"
/*
* System includes
*/
/*
* Qt includes
*/
@@ -22,33 +26,13 @@ DebugWidget::DebugWidget( Preferences* pref, QWidget* parent ) : QWidget( parent
* Store the preferences
*/
m_pref = pref;
}
/*
* Set the debug message
*/
void DebugWidget::setDebugMessage( const QString& message )
{
m_ui->messageLabel->setText( message );
}
/*
* Set the raw data length
*/
void DebugWidget::setRawDataLength( int length )
{
m_ui->rawDataLengthLabel->setText( QString::number( length ) );
}
/*
* Set the raw received message
*/
void DebugWidget::setErrorDataMessage( const QString &message )
{
m_ui->rawDataLabel->setText( message );
/*
* Connect the button
*/
connect( m_ui->test1PushButton, &QPushButton::clicked, this, &DebugWidget::slotHandleTest1Button);
connect( m_ui->test2PushButton, &QPushButton::clicked, this, &DebugWidget::slotHandleTest2Button);
connect( m_ui->test3PushButton, &QPushButton::clicked, this, &DebugWidget::slotHandleTest3Button);
}
@@ -61,15 +45,6 @@ void DebugWidget::setUnreadMail( int unread )
}
/*
* Set the link error message
*/
void DebugWidget::setError( const QString &error )
{
m_ui->errorLabel->setText( error );
}
/*
* Handle a debug state change signal
*/
@@ -79,39 +54,6 @@ void DebugWidget::slotDebugChange()
}
/*
* Handle a debug message signal
*/
void DebugWidget::slotDebugMessage( const QString& message )
{
setDebugMessage( message );
}
/*
* Handle received message length
*/
void DebugWidget::slotReceivedDataLength( qint32 data_len )
{
setRawDataLength( data_len );
}
/*
* Display received message
*/
void DebugWidget::slotReceivedData( const QByteArray& data )
{
setErrorDataMessage( QString( data ) );
/*
* Reply
*/
// QByteArray reply = QString( "\"Hallo other world!\"" ).toUtf8();
// emit signalWriteMessage( reply );
}
/*
* Handle unread mail signal
*/
@@ -122,9 +64,36 @@ void DebugWidget::slotUnreadMail( int unread_mail )
/*
* Handle a receive error
* Handle test button 1 click
*/
void DebugWidget::slotReceiveError( const QString& error )
void DebugWidget::slotHandleTest1Button()
{
setError( error );
emit signalTest1ButtonClicked();
}
/*
* Handle test button 2 click
*/
void DebugWidget::slotHandleTest2Button()
{
emit signalTest2ButtonClicked();
}
/*
* Handle test button 3 click
*/
void DebugWidget::slotHandleTest3Button()
{
emit signalTest3ButtonClicked();
}
/*
* Handle console signal
*/
void DebugWidget::slotConsole( QString message )
{
m_ui->textEdit->append( message );
}

View File

@@ -38,91 +38,65 @@ class DebugWidget : public QWidget
*/
explicit DebugWidget( Preferences* pref, QWidget* parent = nullptr );
/**
* @brief setDebugMessage. Display a debug message.
*
* @param message The message to display.
*/
void setDebugMessage( const QString& message );
/**
* @brief setRawDataLength. Display the error data length.
*
* @param length The raw data length.
*/
void setRawDataLength( int length );
/**
* @brief setRswDataMessage. Display the raw data.
*
* @param message The raw data messsage.
*/
void setErrorDataMessage( const QString &message );
/**
* @brief setUnreadMail. Set the number of unread mails.
*
* @param unread The number of unread mails.
*/
void setUnreadMail( int unread );
/**
* @brief setError. Set the error message.
*
* @param error The error message.
*/
void setError( const QString &error );
void setUnreadMail( int unread );
signals:
/**
* @brief signalWriteMessage
*
* @param message
* @brief signalTestButton1Clicked. Signal the test button was clicked.
*/
void signalWriteMessage( const QByteArray& message );
void signalTest1ButtonClicked();
/**
* @brief signalTestButton2Clicked. Signal the test button was clicked.
*/
void signalTest2ButtonClicked();
/**
* @brief signalTestButton3Clicked. Signal the test button was clicked.
*/
void signalTest3ButtonClicked();
public slots:
/**
* @brief slotDebugChange. The debug state changed.
*/
void slotDebugChange();
/**
* @brief slotDebugMessage
*
* @param message
*/
void slotDebugMessage( const QString& message );
/**
* @brief slotReceivedDataLength. The received data length.
*
* @param data_len The received data length.
*/
void slotReceivedDataLength( qint32 msglen );
/**
* @brief slotReceivedData. The received data.
*
* @param data The received data.
*/
void slotReceivedData( const QByteArray& data );
void slotDebugChange();
/**
* @brief slotSetUnreadMail. Slot for handling unread mail signals.
*
* @param unread_mail The number of unread mails.
*/
void slotUnreadMail( int unread_mail );
void slotUnreadMail( int unread_mail );
/**
* @brief slotReceiveError. Handle receive error signal.
*
* @param error Error message.
* @brief slotHandleTest1Button. Handle a click on the test button.
*/
void slotReceiveError( const QString& error );
void slotHandleTest1Button();
/**
* @brief slotHandleTest2Button. Handle a click on the test button.
*/
void slotHandleTest2Button();
/**
* @brief slotHandleTest2Button. Handle a click on the test button.
*/
void slotHandleTest3Button();
/**
* @brief slotConsole. Handle console signal.
*
* @param message The message for the console.
*/
void slotConsole( QString message );
private:

View File

@@ -19,24 +19,10 @@
<x>10</x>
<y>10</y>
<width>381</width>
<height>281</height>
<height>288</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="5" column="0">
<widget class="QLabel" name="rawDataLengthLabel">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="errorLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
@@ -50,14 +36,7 @@
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QLabel" name="unreadMailLabel">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="1" column="3">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -70,13 +49,16 @@
</property>
</spacer>
</item>
<item row="5" column="1">
<widget class="QLabel" name="rawDataLabel">
<item row="4" column="1">
<widget class="QPushButton" name="test2PushButton">
<property name="text">
<string/>
<string>Test 2</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="4">
<widget class="QTextEdit" name="textEdit"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="unreadMailTextLabel">
<property name="text">
@@ -84,10 +66,24 @@
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="messageLabel">
<item row="4" column="0">
<widget class="QPushButton" name="test1PushButton">
<property name="text">
<string/>
<string>Test 1</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="unreadMailLabel">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QPushButton" name="test3PushButton">
<property name="text">
<string>Test 3</string>
</property>
</widget>
</item>

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

View File

@@ -8,7 +8,7 @@
*/
#include <QApplication>
int main(int argc, char *argv[])
int main( int argc, char *argv[] )
{
QApplication a(argc, argv);
SysTrayX systrayx;

View File

@@ -1,5 +1,17 @@
#include "preferences.h"
/*
* Local includes
*/
/*
* System includes
*/
/*
* Qt includes
*/
/**
* @brief Preferences. Constructor.
@@ -15,6 +27,9 @@ Preferences::Preferences( QObject *parent ) : QObject( parent )
m_icon_mime = "image/png";
m_icon_data = QByteArray();
m_hide_minimize = true;
m_start_minimized = false;
m_debug = false;
}
@@ -31,7 +46,7 @@ Preferences::IconType Preferences::getIconType() const
/*
* Get the icon mime.
*/
bool Preferences::getAppPrefChanged() const
bool Preferences::getAppPrefChanged() const
{
return m_app_pref_changed;
}
@@ -40,7 +55,7 @@ bool Preferences::getAppPrefChanged() const
/*
* Control the sending of preferences changes to the add-on
*/
void Preferences::setAppPrefChanged( bool state )
void Preferences::setAppPrefChanged( bool state )
{
if( m_app_pref_changed != state )
{
@@ -52,7 +67,7 @@ void Preferences::setAppPrefChanged( bool state )
/*
* Set the icon type.
*/
void Preferences::setIconType( IconType icon_type )
void Preferences::setIconType( IconType icon_type )
{
if( m_icon_type != icon_type)
{
@@ -69,7 +84,7 @@ void Preferences::setIconType( IconType icon_type )
/*
* Get the icon mime.
*/
const QString& Preferences::getIconMime() const
const QString& Preferences::getIconMime() const
{
return m_icon_mime;
}
@@ -78,7 +93,7 @@ const QString& Preferences::getIconMime() const
/*
* Set the icon mime.
*/
void Preferences::setIconMime( const QString& icon_mime )
void Preferences::setIconMime( const QString& icon_mime )
{
m_icon_mime = icon_mime;
}
@@ -87,7 +102,7 @@ void Preferences::setIconMime( const QString& icon_mime )
/*
* Get the icon data.
*/
const QByteArray& Preferences::getIconData() const
const QByteArray& Preferences::getIconData() const
{
return m_icon_data;
}
@@ -96,7 +111,7 @@ const QByteArray& Preferences::getIconData() const
/*
* Set the icon data.
*/
void Preferences::setIconData( const QByteArray& icon_data )
void Preferences::setIconData( const QByteArray& icon_data )
{
if( m_icon_data != icon_data )
@@ -112,18 +127,70 @@ void Preferences::setIconData( const QByteArray& icon_data )
/*
* Get the icon data.
* Get the hide on minimize pref.
*/
bool Preferences::getDebug() const
bool Preferences::getHideOnMinimize() const
{
return m_hide_minimize;
}
/*
* Set the hide on minimize pref.
*/
void Preferences::setHideOnMinimize( bool state )
{
if( m_hide_minimize != state )
{
m_hide_minimize = state;
/*
* Tell the world the new preference
*/
emit signalHideOnMinimizeChange();
}
}
/*
* Get the start minmized pref.
*/
bool Preferences::getStartMinimized() const
{
return m_start_minimized;
}
/*
* Set the start minimized pref.
*/
void Preferences::setStartMinimized( bool state )
{
if( m_start_minimized != state )
{
m_start_minimized = state;
/*
* Tell the world the new preference
*/
emit signalStartMinimizedChange();
}
}
/*
* Get the debug state.
*/
bool Preferences::getDebug() const
{
return m_debug;
}
/*
* Set the icon data.
* Set the debug state.
*/
void Preferences::setDebug( bool state )
void Preferences::setDebug( bool state )
{
if( m_debug != state )
{

View File

@@ -33,7 +33,7 @@ class Preferences : public QObject
public:
/**
* @brief Preferences. Constructor.
* @brief Preferences. Constructor. Destructor.
*/
Preferences( QObject *parent = nullptr );
@@ -93,6 +93,34 @@ class Preferences : public QObject
*/
void setIconData( const QByteArray& icon_data );
/**
* @brief getHideOnMinimize. Get the hide on minimize state.
*
* @return The state.
*/
bool getHideOnMinimize() const;
/**
* @brief setHideOnMinimize. Set the hide on minimize state.
*
* @param The state.
*/
void setHideOnMinimize( bool state );
/**
* @brief getStartMinimized. Get the start minimized state.
*
* @return The state.
*/
bool getStartMinimized() const;
/**
* @brief setStartMinimized. Set the start minimized state.
*
* @param The state.
*/
void setStartMinimized( bool state );
/**
* @brief getDebug. Get the debug windows state.
*
@@ -119,6 +147,16 @@ class Preferences : public QObject
*/
void signalIconDataChange();
/**
* @brief signalHideOnMinimizeChange. Signal a hide on mnimize state change.
*/
void signalHideOnMinimizeChange();
/**
* @brief signalStartMinimizedChange. Signal a start minimized state change.
*/
void signalStartMinimizedChange();
/**
* @brief signalDebugChange. Signal a debug state change.
*/
@@ -146,6 +184,16 @@ class Preferences : public QObject
*/
QByteArray m_icon_data;
/**
* @brief m_hide_minimize. Hide the minimized window.
*/
bool m_hide_minimize;
/**
* @brief m_start_minimized. Start TB minimized.
*/
bool m_start_minimized;
/**
* @brief m_debug. Display debug window.
*/

View File

@@ -6,28 +6,178 @@
<rect>
<x>0</x>
<y>0</y>
<width>553</width>
<height>544</height>
<width>292</width>
<height>326</height>
</rect>
</property>
<property name="windowTitle">
<string>SysTray-X Preferences</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Windows</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QCheckBox" name="hideOnMinimizeCheckBox">
<property name="text">
<string>Minimizing window hides to tray</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="startMinimizedCheckBox">
<property name="text">
<string>Start application minimized</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="iconTypeGroupBox">
<property name="title">
<string>Mail notification icon</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item>
<widget class="QRadioButton" name="blankRadioButton">
<property name="text">
<string>Blank icon</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">iconTypeGroup</string>
</attribute>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item>
<widget class="QRadioButton" name="newMailButton">
<property name="text">
<string>New mail icon</string>
</property>
<attribute name="buttonGroup">
<string notr="true">iconTypeGroup</string>
</attribute>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item>
<widget class="QRadioButton" name="customRadioButton">
<property name="text">
<string>Custom icon</string>
</property>
<attribute name="buttonGroup">
<string notr="true">iconTypeGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QLabel" name="imageLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="chooseCustomButton">
<property name="text">
<string>Choose</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="debugWindowCheckBox">
<property name="text">
<string>Display debug window</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="4" column="2">
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -37,149 +187,6 @@
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="iconTypeGroupBox">
<property name="title">
<string>Mail notification icon</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item>
<widget class="QRadioButton" name="blankRadioButton">
<property name="text">
<string>Blank icon</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">iconTypeGroup</string>
</attribute>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item>
<widget class="QRadioButton" name="newMailButton">
<property name="text">
<string>New mail icon</string>
</property>
<attribute name="buttonGroup">
<string notr="true">iconTypeGroup</string>
</attribute>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item>
<widget class="QRadioButton" name="customRadioButton">
<property name="text">
<string>Custom icon</string>
</property>
<attribute name="buttonGroup">
<string notr="true">iconTypeGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QLabel" name="imageLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="chooseCustomButton">
<property name="text">
<string>Choose</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="debugWindowCheckBox">
<property name="text">
<string>Display debug window</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>

View File

@@ -52,16 +52,34 @@ PreferencesDialog::PreferencesDialog( SysTrayXLink *link, Preferences *pref, QWi
/*
* Set the debug state
*/
void PreferencesDialog::setDebug( bool state )
void PreferencesDialog::setDebug( bool state )
{
m_ui->debugWindowCheckBox->setChecked( state );
}
/*
* Set the hide on minimize state
*/
void PreferencesDialog::setHideOnMinimize( bool state )
{
m_ui->hideOnMinimizeCheckBox->setChecked( state );
}
/*
* Set the start minimized state
*/
void PreferencesDialog::setStartMinimized( bool state )
{
m_ui->startMinimizedCheckBox->setChecked( state );
}
/*
* Set the icon type
*/
void PreferencesDialog::setIconType( Preferences::IconType icon_type )
void PreferencesDialog::setIconType( Preferences::IconType icon_type )
{
( m_ui->iconTypeGroup->button( icon_type ) )->setChecked( true );
}
@@ -69,7 +87,7 @@ void PreferencesDialog::setIconType( Preferences::IconType icon_type )
/*
* Set the icon
*/
void PreferencesDialog::setIcon( const QString& icon_mime, const QByteArray& icon )
void PreferencesDialog::setIcon( const QString& icon_mime, const QByteArray& icon )
{
/*
* Store the new icon
@@ -87,7 +105,7 @@ void PreferencesDialog::setIcon( const QString& icon_mime, const QByteArray& ico
/*
* Set the icon
*/
void PreferencesDialog::setIcon()
void PreferencesDialog::setIcon()
{
/*
* Convert data to pixmap
@@ -105,7 +123,7 @@ void PreferencesDialog::setIcon()
/*
* Handle the accept signal
*/
void PreferencesDialog::slotAccept()
void PreferencesDialog::slotAccept()
{
/*
* Settings changed by app
@@ -119,6 +137,9 @@ void PreferencesDialog::slotAccept()
m_pref->setIconMime( m_tmp_icon_mime );
m_pref->setIconData( m_tmp_icon_data );
m_pref->setHideOnMinimize( m_ui->hideOnMinimizeCheckBox->isChecked() );
m_pref->setStartMinimized( m_ui->startMinimizedCheckBox->isChecked() );
m_pref->setDebug( m_ui->debugWindowCheckBox->isChecked() );
/*
@@ -136,7 +157,7 @@ void PreferencesDialog::slotAccept()
/*
* Handle the choose button
*/
void PreferencesDialog::slotFileSelect()
void PreferencesDialog::slotFileSelect()
{
QFileDialog file_dialog( this, tr( "Open Image" ), "", tr( "Image Files (*.png *.jpg *.bmp)" ) );
@@ -161,16 +182,33 @@ void PreferencesDialog::slotFileSelect()
/*
* Handle the debug change signal
*/
void PreferencesDialog::slotDebugChange()
void PreferencesDialog::slotDebugChange()
{
setDebug( m_pref->getDebug() );
}
/*
* Handle the hide on minimize change signal
*/
void PreferencesDialog::slotHideOnMinimizeChange()
{
setHideOnMinimize( m_pref->getHideOnMinimize() );
}
/*
* Handle the start minimized change signal
*/
void PreferencesDialog::slotStartMinimizedChange()
{
setStartMinimized( m_pref->getStartMinimized() );
}
/*
* Handle the icon type change signal
*/
void PreferencesDialog::slotIconTypeChange()
void PreferencesDialog::slotIconTypeChange()
{
setIconType( m_pref->getIconType() );
}
@@ -179,7 +217,7 @@ void PreferencesDialog::slotIconTypeChange()
/*
* Handle the icon data change signal
*/
void PreferencesDialog::slotIconDataChange()
void PreferencesDialog::slotIconDataChange()
{
m_tmp_icon_mime = m_pref->getIconMime();
m_tmp_icon_data = m_pref->getIconData();

View File

@@ -46,14 +46,28 @@ class PreferencesDialog : public QDialog
*
* @param state The state.
*/
void setDebug( bool state );
void setDebug( bool state );
/**
* @brief setHideOnMinimize. Set the hide on minimize state.
*
* @param state The state.
*/
void setHideOnMinimize( bool state );
/**
* @brief setStartMinimized. Set the start minimized state.
*
* @param state The state.
*/
void setStartMinimized( bool state );
/**
* @brief setIconType. Set the icon type.
*
* @param icon_type The icon type.
*/
void setIconType( Preferences::IconType icon_type );
void setIconType( Preferences::IconType icon_type );
/**
* @brief setIcon. Set the icon.
@@ -61,22 +75,15 @@ class PreferencesDialog : public QDialog
* @param icon The icon mime.
* @param icon The icon data.
*/
void setIcon( const QString& icon_mime, const QByteArray& icon );
void setIcon( const QString& icon_mime, const QByteArray& icon );
/**
* @brief setIcon. Set the icon.
*/
void setIcon();
void setIcon();
signals:
/**
* @brief signalDebugMessage. Signal a debug message.
*
* @param message The message.
*/
void signalDebugMessage( QString message );
/**
* @brief signalUpdateSysTray. Signal to update the system tray icon.
*/
@@ -89,6 +96,16 @@ class PreferencesDialog : public QDialog
*/
void slotDebugChange();
/**
* @brief slotHideOnMinimizeChange. Slot for handling hide on minimize change signals.
*/
void slotHideOnMinimizeChange();
/**
* @brief slotStartMinimizedChange. Slot for handling start minimized change signals.
*/
void slotStartMinimizedChange();
/**
* @brief slotIconTypeChange. Slot for handling icon type change signals.
*/

View File

@@ -14,11 +14,13 @@
*/
#include <QCoreApplication>
#include <QMenu>
#include <QStyle>
#include <QIcon>
/*
* Constants
*/
const QString SysTrayX::JSON_PREF_REQUEST = "{\"preferences\":{}}";
const QString SysTrayX::JSON_PREF_REQUEST = "{\"preferences\":{}}";
/*
@@ -34,7 +36,7 @@ SysTrayX::SysTrayX( QObject *parent ) : QObject( parent )
/*
* Setup window control
*/
m_win_ctrl = new WindowCtrl();
m_win_ctrl = new WindowCtrl( m_preferences );
/*
* Setup the link
@@ -63,20 +65,12 @@ SysTrayX::SysTrayX( QObject *parent ) : QObject( parent )
/*
* Connect debug link signals
*/
connect( m_link, &SysTrayXLink::signalReceivedDataLength, m_debug, &DebugWidget::slotReceivedDataLength );
connect( m_link, &SysTrayXLink::signalReceivedData, m_debug, &DebugWidget::slotReceivedData );
connect( m_link, &SysTrayXLink::signalUnreadMail, m_debug, &DebugWidget::slotUnreadMail );
connect( m_link, &SysTrayXLink::signalLinkReceiveError, m_debug, &DebugWidget::slotReceiveError );
connect( m_debug, &DebugWidget::signalWriteMessage, m_link, &SysTrayXLink::slotLinkWrite );
connect( m_pref_dialog, &PreferencesDialog::signalDebugMessage, m_debug, &DebugWidget::slotDebugMessage );
connect( m_tray_icon, &SysTrayXIcon::signalDebugMessage, m_debug, &DebugWidget::slotDebugMessage );
connect( m_link, &SysTrayXLink::signalDebugMessage, m_debug, &DebugWidget::slotDebugMessage );
connect( m_win_ctrl, &WindowCtrl::signalDebugMessage, m_debug, &DebugWidget::slotDebugMessage );
connect( m_win_ctrl, &WindowCtrl::signalConsole, m_debug, &DebugWidget::slotConsole );
connect( m_debug, &DebugWidget::signalTest1ButtonClicked, m_win_ctrl, &WindowCtrl::slotWindowTest1 );
connect( m_debug, &DebugWidget::signalTest2ButtonClicked, m_win_ctrl, &WindowCtrl::slotWindowTest2 );
connect( m_debug, &DebugWidget::signalTest3ButtonClicked, m_win_ctrl, &WindowCtrl::slotWindowTest3 );
/*
* Connect preferences signals
@@ -84,12 +78,20 @@ SysTrayX::SysTrayX( QObject *parent ) : QObject( parent )
connect( m_preferences, &Preferences::signalIconTypeChange, m_tray_icon, &SysTrayXIcon::slotIconTypeChange );
connect( m_preferences, &Preferences::signalIconDataChange, m_tray_icon, &SysTrayXIcon::slotIconDataChange );
connect( m_preferences, &Preferences::signalHideOnMinimizeChange, m_win_ctrl, &WindowCtrl::slotHideOnMinimizeChange );
connect( m_preferences, &Preferences::signalStartMinimizedChange, m_win_ctrl, &WindowCtrl::slotStartMinimizedChange );
connect( m_preferences, &Preferences::signalIconTypeChange, m_pref_dialog, &PreferencesDialog::slotIconTypeChange );
connect( m_preferences, &Preferences::signalIconDataChange, m_pref_dialog, &PreferencesDialog::slotIconDataChange );
connect( m_preferences, &Preferences::signalHideOnMinimizeChange, m_pref_dialog, &PreferencesDialog::slotHideOnMinimizeChange );
connect( m_preferences, &Preferences::signalStartMinimizedChange, m_pref_dialog, &PreferencesDialog::slotStartMinimizedChange );
connect( m_preferences, &Preferences::signalDebugChange, m_pref_dialog, &PreferencesDialog::slotDebugChange );
connect( m_preferences, &Preferences::signalIconTypeChange, m_link, &SysTrayXLink::slotIconTypeChange );
connect( m_preferences, &Preferences::signalIconDataChange, m_link, &SysTrayXLink::slotIconDataChange );
connect( m_preferences, &Preferences::signalHideOnMinimizeChange, m_link, &SysTrayXLink::slotHideOnMinimizeChange );
connect( m_preferences, &Preferences::signalStartMinimizedChange, m_link, &SysTrayXLink::slotStartMinimizedChange );
connect( m_preferences, &Preferences::signalDebugChange, m_link, &SysTrayXLink::slotDebugChange );
connect( m_preferences, &Preferences::signalDebugChange, m_debug, &DebugWidget::slotDebugChange );
@@ -98,8 +100,9 @@ SysTrayX::SysTrayX( QObject *parent ) : QObject( parent )
* Connect link signals
*/
connect( m_link, &SysTrayXLink::signalUnreadMail, m_tray_icon, &SysTrayXIcon::slotSetUnreadMail );
connect( m_link, &SysTrayXLink::signalShutdown, this, &SysTrayX::slotShutdown );
connect( m_link, &SysTrayXLink::signalAddOnShutdown, this, &SysTrayX::slotAddOnShutdown );
connect( m_link, &SysTrayXLink::signalWindowState, m_win_ctrl, &WindowCtrl::slotWindowState );
connect( m_link, &SysTrayXLink::signalTitle, m_win_ctrl, &WindowCtrl::slotWindowTitle );
/*
* Connect window signals
@@ -112,6 +115,11 @@ SysTrayX::SysTrayX( QObject *parent ) : QObject( parent )
*/
connect( m_tray_icon, &SysTrayXIcon::signalShowHide, m_win_ctrl, &WindowCtrl::slotShowHide );
/*
* SysTrayX
*/
connect( this, &SysTrayX::signalClose, m_win_ctrl, &WindowCtrl::slotClose );
/*
* Request preferences from add-on
*/
@@ -122,7 +130,7 @@ SysTrayX::SysTrayX( QObject *parent ) : QObject( parent )
/*
* Send a preferences request
*/
void SysTrayX::getPreferences()
void SysTrayX::getPreferences()
{
/*
* Request preferences from add-on
@@ -135,35 +143,26 @@ void SysTrayX::getPreferences()
/*
* Create the actions for the system tray icon menu
*/
void SysTrayX::createActions()
void SysTrayX::createActions()
{
/*
m_minimizeAction = new QAction(tr("Mi&nimize"), this);
connect( m_minimizeAction, &QAction::triggered, this, &QWidget::hide );
m_maximizeAction = new QAction(tr("Ma&ximize"), this);
connect( m_maximizeAction, &QAction::triggered, this, &QWidget::showMaximized );
m_restoreAction = new QAction(tr("&Restore"), this);
connect( m_restoreAction, &QAction::triggered, this, &QWidget::showNormal );
*/
m_showhide_action = new QAction(tr("&Show/Hide"), this);
m_showhide_action->setIcon( QIcon( ":/files/icons/window-restore.png" ) );
connect( m_showhide_action, &QAction::triggered, m_win_ctrl, &WindowCtrl::slotShowHide );
m_pref_action = new QAction(tr("&Preferences"), this);
m_pref_action->setIcon( QIcon( ":/files/icons/gtk-preferences.png" ) );
connect( m_pref_action, &QAction::triggered, m_pref_dialog, &PreferencesDialog::showNormal );
m_quit_action = new QAction(tr("&Quit"), this);
connect( m_quit_action, &QAction::triggered, qApp, &QCoreApplication::quit );
m_quit_action = new QAction( tr("&Quit"), this );
m_quit_action->setIcon( QIcon( ":/files/icons/window-close.png" ) );
connect( m_quit_action, &QAction::triggered, this, &SysTrayX::slotShutdown );
}
/*
* Create the system tray icon
*/
void SysTrayX::createTrayIcon()
void SysTrayX::createTrayIcon()
{
/*
* Setup menu actions
@@ -174,9 +173,6 @@ void SysTrayX::createTrayIcon()
* Setup menu
*/
m_tray_icon_menu = new QMenu();
// m_trayIconMenu->addAction( m_minimizeAction );
// m_trayIconMenu->addAction( m_maximizeAction );
// m_trayIconMenu->addAction( m_restoreAction );
m_tray_icon_menu->addAction( m_showhide_action );
m_tray_icon_menu->addSeparator();
@@ -200,12 +196,29 @@ void SysTrayX::createTrayIcon()
/*
* Quit the app
* Quit the app by add-on request
*/
void SysTrayX::slotShutdown()
void SysTrayX::slotAddOnShutdown()
{
/*
* Let's quit
*/
QCoreApplication::quit();
}
/*
* Quit the app by quit menu
*/
void SysTrayX::slotShutdown()
{
/*
* Close the TB window
*/
emit signalClose();
/*
* Let's quit
*/
QCoreApplication::quit();
}

View File

@@ -49,17 +49,17 @@ class SysTrayX : public QObject
/**
* @brief SysTrayX::getPreferences
*/
void getPreferences();
void getPreferences();
/**
* @brief createTrayIcon. Create the system tray icon.
*/
void createTrayIcon();
void createTrayIcon();
/**
* @brief createActions. Create the menu actions.
*/
void createActions();
void createActions();
signals:
@@ -68,58 +68,68 @@ class SysTrayX : public QObject
*
* @param message
*/
void signalWriteMessage( QByteArray message );
void signalWriteMessage( QByteArray message );
/**
* @brief signalClose. Signal close all TB windows.
*/
void signalClose();
private slots:
/**
* @brief slotShutdown Shutdown the app.
*/
void slotShutdown();
* @brief slotAddOnShutdown. Hnadle shutdown request from the add-on.
*/
void slotAddOnShutdown();
/**
* @brief slotShutdown. Hnadle shutdown request from the menu.
*/
void slotShutdown();
private:
/**
* @brief m_preferences. Pointer to the preferences storage.
*/
Preferences *m_preferences;
Preferences* m_preferences;
/**
* @brief m_debug
*/
DebugWidget *m_debug;
DebugWidget* m_debug;
/**
* @brief m_win_ctrl. Pointer to the window control.
*/
WindowCtrl *m_win_ctrl;
WindowCtrl* m_win_ctrl;
/**
* @brief m_link. Pointer to the link object.
*/
SysTrayXLink *m_link;
SysTrayXLink* m_link;
/**
* @brief m_pref_dialog. Pointer to the preferences dialog.
*/
PreferencesDialog *m_pref_dialog;
PreferencesDialog* m_pref_dialog;
/**
* @brief m_tray_icon. Pointer to the system tray icon.
*/
SysTrayXIcon *m_tray_icon;
SysTrayXIcon* m_tray_icon;
/**
* @brief m_tray_icon_menu. Pointer to the tray icon menu.
*/
QMenu *m_tray_icon_menu;
QMenu* m_tray_icon_menu;
/**
* @brief m_xxxx_action. Pointer to the menu actions.
*/
QAction *m_pref_action;
QAction *m_quit_action;
QAction *m_showhide_action;
QAction* m_pref_action;
QAction* m_quit_action;
QAction* m_showhide_action;
};
#endif // SYSTRAYX_H

View File

@@ -19,7 +19,8 @@
/*
* Constructor
*/
SysTrayXIcon::SysTrayXIcon( SysTrayXLink *link, Preferences *pref, QObject *parent ) : QSystemTrayIcon( QIcon(), parent )
SysTrayXIcon::SysTrayXIcon( SysTrayXLink* link, Preferences* pref, QObject* parent )
: QSystemTrayIcon( QIcon( ":/files/icons/Thunderbird.png" ), parent )
{
/*
* Initialize
@@ -36,7 +37,7 @@ SysTrayXIcon::SysTrayXIcon( SysTrayXLink *link, Preferences *pref, QObject *pare
/*
* Set the icon type
*/
void SysTrayXIcon::setIconType( Preferences::IconType icon_type )
void SysTrayXIcon::setIconType( Preferences::IconType icon_type )
{
if( icon_type != m_icon_type )
{
@@ -56,7 +57,7 @@ void SysTrayXIcon::setIconType( Preferences::IconType icon_type )
/*
* Set the icon mime
*/
void SysTrayXIcon::setIconMime( const QString& icon_mime )
void SysTrayXIcon::setIconMime( const QString& icon_mime )
{
if( m_icon_mime != icon_mime )
{
@@ -71,7 +72,7 @@ void SysTrayXIcon::setIconMime( const QString& icon_mime )
/*
* Set the icon type
*/
void SysTrayXIcon::setIconData( const QByteArray& icon_data )
void SysTrayXIcon::setIconData( const QByteArray& icon_data )
{
if( m_icon_data != icon_data )
{
@@ -91,7 +92,7 @@ void SysTrayXIcon::setIconData( const QByteArray& icon_data )
/*
* Set the number of unread mails
*/
void SysTrayXIcon::setUnreadMail( int unread_mail )
void SysTrayXIcon::setUnreadMail( int unread_mail )
{
if( unread_mail != m_unread_mail ) {
@@ -111,33 +112,38 @@ void SysTrayXIcon::setUnreadMail( int unread_mail )
/*
* Set and render the icon in the system tray
*/
void SysTrayXIcon::renderIcon()
void SysTrayXIcon::renderIcon()
{
QPixmap pixmap;
switch( m_icon_type )
if( m_unread_mail > 0 )
{
case Preferences::PREF_BLANK_ICON:
switch( m_icon_type )
{
pixmap = QPixmap( ":/files/icons/blank-icon.png" );
break;
}
case Preferences::PREF_BLANK_ICON:
{
pixmap = QPixmap( ":/files/icons/blank-icon.png" );
break;
}
case Preferences::PREF_NEWMAIL_ICON:
{
QIcon new_mail = QIcon::fromTheme("mail-unread", QIcon(":/files/icons/blank-icon.png"));
pixmap = new_mail.pixmap( 256, 256 );
break;
}
case Preferences::PREF_NEWMAIL_ICON:
{
QIcon new_mail = QIcon::fromTheme("mail-unread", QIcon(":/files/icons/blank-icon.png"));
pixmap = new_mail.pixmap( 256, 256 );
break;
}
case Preferences::PREF_CUSTOM_ICON:
{
pixmap.loadFromData( m_icon_data );
break;
case Preferences::PREF_CUSTOM_ICON:
{
pixmap.loadFromData( m_icon_data );
break;
}
}
}
QString number = QString::number( m_unread_mail );
else
{
pixmap = QPixmap( ":/files/icons/Thunderbird.png" );
}
if( m_unread_mail > 0 )
{
@@ -148,7 +154,12 @@ void SysTrayXIcon::renderIcon()
painter.setFont( QFont("Sans") );
QString number = QString::number( m_unread_mail );
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
double factor = pixmap.width() / ( 3 * painter.fontMetrics().width( number ) );
#else
double factor = pixmap.width() / ( 3 * painter.fontMetrics().horizontalAdvance( number ) );
#endif
QFont font = painter.font();
font.setPointSizeF( font.pointSizeF() * factor );
font.setBold( true );
@@ -167,7 +178,7 @@ void SysTrayXIcon::renderIcon()
/*
* Handle unread mail signal
*/
void SysTrayXIcon::slotSetUnreadMail( int unread_mail )
void SysTrayXIcon::slotSetUnreadMail( int unread_mail )
{
setUnreadMail( unread_mail );
}
@@ -176,7 +187,7 @@ void SysTrayXIcon::slotSetUnreadMail( int unread_mail )
/*
* Handle the icon type change signal
*/
void SysTrayXIcon::slotIconTypeChange()
void SysTrayXIcon::slotIconTypeChange()
{
setIconType( m_pref->getIconType() );
}
@@ -185,7 +196,7 @@ void SysTrayXIcon::slotIconTypeChange()
/*
* Handle the icon data change signal
*/
void SysTrayXIcon::slotIconDataChange()
void SysTrayXIcon::slotIconDataChange()
{
setIconMime( m_pref->getIconMime() );
setIconData( m_pref->getIconData() );
@@ -195,7 +206,7 @@ void SysTrayXIcon::slotIconDataChange()
/*
* Handle activation of the tray icon
*/
void SysTrayXIcon::slotIconActivated( QSystemTrayIcon::ActivationReason reason )
void SysTrayXIcon::slotIconActivated( QSystemTrayIcon::ActivationReason reason )
{
switch (reason) {
case QSystemTrayIcon::Trigger:

View File

@@ -31,56 +31,49 @@ class SysTrayXIcon : public QSystemTrayIcon
*
* @param parent My parent.
*/
SysTrayXIcon( SysTrayXLink *link, Preferences *pref, QObject *parent = nullptr );
SysTrayXIcon( SysTrayXLink* link, Preferences* pref, QObject* parent = nullptr );
/**
* @brief setIconType. Set the sytem tray icon type.
*
* @param icon_type The icon type
*/
void setIconType( Preferences::IconType icon_type );
void setIconType( Preferences::IconType icon_type );
/**
* @brief setIconMime. Set the sytem tray icon mime.
*
* @param icon_mime The icon mime
*/
void setIconMime( const QString& icon_mime );
void setIconMime( const QString& icon_mime );
/**
* @brief setIconData. Set the custom icon data.
*
* @param icon_data The icon data.
*/
void setIconData( const QByteArray& icon_data );
void setIconData( const QByteArray& icon_data );
/**
* @brief setUnreadMail. Set the number of unread mails.
*
* @param unread_mail The number of unread mails.
*/
void setUnreadMail( int unread_mail );
void setUnreadMail( int unread_mail );
private:
/**
* @brief setIcon. Set a new rendered icon.
*/
void renderIcon();
void renderIcon();
signals:
/**
* @brief signalDebugMessage. Signal a debug message.
*
* @param message The message.
*/
void signalDebugMessage( QString message );
/**
* @brief signalShowHide. Signal show / hide window.
*/
void signalShowHide();
void signalShowHide();
public slots:
@@ -89,17 +82,17 @@ class SysTrayXIcon : public QSystemTrayIcon
*
* @param unread_mail The number of unread mails.
*/
void slotSetUnreadMail( int unread_mail );
void slotSetUnreadMail( int unread_mail );
/**
* @brief slotIconTypeChange. Slot for handling icon type change signals.
*/
void slotIconTypeChange();
void slotIconTypeChange();
/**
* @brief slotIconDataChange. Slot for handling icon data change signals.
*/
void slotIconDataChange();
void slotIconDataChange();
private slots:
@@ -108,24 +101,24 @@ class SysTrayXIcon : public QSystemTrayIcon
*
* @param reason Activation reason.
*/
void slotIconActivated( QSystemTrayIcon::ActivationReason reason );
void slotIconActivated( QSystemTrayIcon::ActivationReason reason );
private:
/**
* @brief m_link. Pointer to the link.
*/
SysTrayXLink *m_link;
SysTrayXLink* m_link;
/**
* @brief m_pref Pointer to the preferences storage.
*/
Preferences *m_pref;
Preferences* m_pref;
/**
* @brief m_icon_type. Storage for the icon type.
*/
Preferences::IconType m_icon_type;
Preferences::IconType m_icon_type;
/**
* @brief m_icon_mime. Storage for the icon mime.
@@ -135,7 +128,7 @@ class SysTrayXIcon : public QSystemTrayIcon
/**
* @brief m_icon_data. Storage for the icon.
*/
QByteArray m_icon_data;
QByteArray m_icon_data;
/**
* @brief m_unread_mail. Storage for the number of unread mails.

View File

@@ -104,24 +104,41 @@ void SysTrayXLinkReader::stopThread()
*/
void SysTrayXLinkReader::slotWorker()
{
int error_count = 0;
while( m_doWork )
{
qint32 data_len;
std::cin.read( reinterpret_cast< char* >( &data_len ), sizeof( qint32 ) );
emit signalReceivedDataLength( data_len );
if( data_len > 0)
{
QByteArray data( data_len, 0 );
std::cin.read( data.data(), data_len );
emit signalReceivedData( data );
/*
* Send the data to my parent
*/
emit signalReceivedMessage( data );
/*
* Send the data to my parent
*/
if( data.at( 0 ) == '{' )
{
emit signalReceivedMessage( data );
error_count = 0;
}
else
{
error_count++;
if( error_count > 20 )
{
emit signalAddOnShutdown();
}
}
}
}
@@ -165,11 +182,7 @@ SysTrayXLink::SysTrayXLink( Preferences* pref )
connect( m_reader_thread, &QThread::finished, reader, &QObject::deleteLater );
connect( reader, &SysTrayXLinkReader::signalReceivedMessage, this, &SysTrayXLink::slotLinkRead );
connect( reader, &SysTrayXLinkReader::signalDebugMessage, this, &SysTrayXLink::slotDebugMessage );
connect( reader, &SysTrayXLinkReader::signalReceivedDataLength, this, &SysTrayXLink::slotReceivedDataLength );
connect( reader, &SysTrayXLinkReader::signalReceivedData, this, &SysTrayXLink::slotReceivedData );
connect( reader, &SysTrayXLinkReader::signalAddOnShutdown, this, &SysTrayXLink::slotAddOnShutdown );
connect( m_reader_thread, &QThread::started, reader, &SysTrayXLinkReader::startThread, Qt::QueuedConnection );
m_reader_thread->start();
@@ -210,15 +223,6 @@ void SysTrayXLink::sendPreferences()
*/
EncodePreferences( *m_pref );
/*
QFile dump("/home/maxime/dumpJSON_app2addon.txt");
dump.open(QIODevice::WriteOnly );
dump.write( m_pref_json_doc.toJson( QJsonDocument::Compact ).data(), m_pref_json_doc.toJson( QJsonDocument::Compact ).length() );
dump.close();
*/
/*
* Send them to the add-on
*/
@@ -290,9 +294,15 @@ void SysTrayXLink::DecodeMessage( const QByteArray& message )
emit signalUnreadMail( unreadMail );
}
if( jsonObject.contains( "title" ) && jsonObject[ "title" ].isString() )
{
QString title = jsonObject[ "title" ].toString();
emit signalTitle( title );
}
if( jsonObject.contains( "shutdown" ) && jsonObject[ "shutdown" ].isString() )
{
emit signalShutdown();
emit signalAddOnShutdown();
}
if( jsonObject.contains( "window" ) && jsonObject[ "window" ].isString() )
@@ -303,22 +313,9 @@ void SysTrayXLink::DecodeMessage( const QByteArray& message )
if( jsonObject.contains( "preferences" ) && jsonObject[ "preferences" ].isObject() )
{
/*
QFile dump("/home/maxime/dumpJSON_addon2app.txt");
dump.open(QIODevice::WriteOnly );
dump.write( message.data(), message.length() );
dump.close();
*/
DecodePreferences( jsonObject[ "preferences" ].toObject() );
}
}
else
{
emit signalLinkReceiveError( jsonError.errorString() );
}
}
@@ -360,6 +357,26 @@ void SysTrayXLink::DecodePreferences( const QJsonObject& pref )
m_pref->setIconData( QByteArray::fromBase64( icon_base64.toUtf8() ) );
}
if( pref.contains( "hideOnMinimize" ) && pref[ "hideOnMinimize" ].isString() )
{
bool hide_minimize = pref[ "hideOnMinimize" ].toString() == "true";
/*
* Store the new hide on minimize state
*/
m_pref->setHideOnMinimize( hide_minimize );
}
if( pref.contains( "startMinimized" ) && pref[ "startMinimized" ].isString() )
{
bool start_minimized = pref[ "startMinimized" ].toString() == "true";
/*
* Store the new start minimized state
*/
m_pref->setStartMinimized( start_minimized );
}
if( pref.contains( "debug" ) && pref[ "debug" ].isString() )
{
bool debug = pref[ "debug" ].toString() == "true";
@@ -382,6 +399,8 @@ void SysTrayXLink::EncodePreferences( const Preferences& pref )
*/
QJsonObject prefObject;
prefObject.insert("debug", QJsonValue::fromVariant( QString( pref.getDebug() ? "true" : "false" ) ) );
prefObject.insert("hideOnMinimize", QJsonValue::fromVariant( QString( pref.getHideOnMinimize() ? "true" : "false" ) ) );
prefObject.insert("startMinimized", QJsonValue::fromVariant( QString( pref.getStartMinimized() ? "true" : "false" ) ) );
prefObject.insert("iconType", QJsonValue::fromVariant( QString::number( pref.getIconType() ) ) );
prefObject.insert("iconMime", QJsonValue::fromVariant( pref.getIconMime() ) );
prefObject.insert("icon", QJsonValue::fromVariant( QString( pref.getIconData().toBase64() ) ) );
@@ -397,29 +416,11 @@ void SysTrayXLink::EncodePreferences( const Preferences& pref )
/*
* Handle the debug message from the reader thread
* Relay shutdown signal
*/
void SysTrayXLink::slotDebugMessage( QString message )
void SysTrayXLink::slotAddOnShutdown()
{
emit signalDebugMessage( message );
}
/*
* Handle data length signal from reader thread
*/
void SysTrayXLink::slotReceivedDataLength( qint32 data_len )
{
emit signalReceivedDataLength( data_len );
}
/*
* Handle data signal from read thread
*/
void SysTrayXLink::slotReceivedData( QByteArray data )
{
emit signalReceivedData( data );
emit signalAddOnShutdown();
}
@@ -428,11 +429,6 @@ void SysTrayXLink::slotReceivedData( QByteArray data )
*/
void SysTrayXLink::slotLinkRead( QByteArray message )
{
/*
* Debug
*/
// m_dump->write( message );
/*
* Decode the message
*/
@@ -441,18 +437,33 @@ void SysTrayXLink::slotLinkRead( QByteArray message )
/*
* write the output
* Handle a debug state change signal
*/
void SysTrayXLink::slotLinkWrite( QByteArray message )
void SysTrayXLink::slotDebugChange()
{
linkWrite( message );
if( m_pref->getAppPrefChanged() )
{
sendPreferences();
}
}
/*
* Handle a debug state change signal
* Handle a hide on minimize state change signal
*/
void SysTrayXLink::slotDebugChange()
void SysTrayXLink::slotHideOnMinimizeChange()
{
if( m_pref->getAppPrefChanged() )
{
sendPreferences();
}
}
/*
* Handle a start minimized state change signal
*/
void SysTrayXLink::slotStartMinimizedChange()
{
if( m_pref->getAppPrefChanged() )
{

View File

@@ -57,27 +57,6 @@ class SysTrayXLinkReader : public QObject
signals:
/**
* @brief signalDebugMessage
*
* @param message The message.
*/
void signalDebugMessage( QString message );
/**
* @brief signalReceivedDataLength
*
* @param data_len The length of the received data.
*/
void signalReceivedDataLength( qint32 data_len );
/**
* @brief signalReceivedData
*
* @param data The received data.
*/
void signalReceivedData( QByteArray data );
/**
* @brief signalReceivedMessage. Signal the received message.
*
@@ -85,6 +64,11 @@ class SysTrayXLinkReader : public QObject
*/
void signalReceivedMessage( QByteArray message );
/**
* @brief signalAddOnShutdown. Signal to shutdown the app.
*/
void signalAddOnShutdown();
private:
/**
@@ -162,43 +146,20 @@ class SysTrayXLink : public QObject
signals:
/**
* @brief signalShutdown. Signal to shutdown the app.
* @brief signalTitle. Signal to title the app.
*/
void signalShutdown();
void signalTitle( QString title );
/**
* @brief signalAddOnShutdown. Signal to shutdown the app.
*/
void signalAddOnShutdown();
/**
* @brief signalWindowState. Signal a change in the window state.
*/
void signalWindowState( QString state );
/**
* @brief signalReceivedDataLength
*
* @param data_len The received data length.
*/
void signalReceivedDataLength( qint32 data_len );
/**
* @brief signalReceivedData
*
* @param data The data received.
*/
void signalReceivedData( QByteArray data );
/**
* @brief signalLinkReceiveError. Cannot parse received JSON message.
*
* @param error JSON error message
*/
void signalLinkReceiveError( QString error );
/**
* @brief signalDebugMessage. Signal a debug message.
*
* @param message The message.
*/
void signalDebugMessage( QString message );
/**
* @brief signalUnreadMail. Signal numder of unread mails.
*
@@ -214,9 +175,14 @@ class SysTrayXLink : public QObject
void slotDebugChange();
/**
* @brief slotLinkWrite. Write the link.
* @brief slotHideOnMinimizeChange. Handle a change in hide on minimize state.
*/
void slotLinkWrite( QByteArray message );
void slotHideOnMinimizeChange();
/**
* @brief slotStartMinimizeChange. Handle a change in start minimized state.
*/
void slotStartMinimizedChange();
/**
* @brief slotIconTypeChange. Slot for handling icon type change signals.
@@ -240,32 +206,16 @@ class SysTrayXLink : public QObject
private slots:
/**
* @brief slotDebugMessage. Handle the signal for a debuf message from the reader thread.
*
* @param message The message.
*/
void slotDebugMessage( QString message );
/**
* @brief slotReceivedDataLength. Handle data length signal from the reader thread.
*
* @param data_len The data length.
*/
void slotReceivedDataLength( qint32 data_len );
/**
* @brief signalReceivedData. Handle data signal from the reader thread.
*
* @param data The data.
*/
void slotReceivedData( QByteArray data );
/**
* @brief slotLinkRead. Read the link.
*/
void slotLinkRead( QByteArray message );
/**
* @brief slotAddOnShutdown. Handle sahutdown signal from reader thread.
*/
void slotAddOnShutdown();
private:
/**
@@ -278,11 +228,6 @@ class SysTrayXLink : public QObject
*/
Preferences* m_pref;
/**
* @brief m_dump. Pointer to dump file.
*/
QFile* m_dump;
/**
* @brief m_pref_json_doc. Temporary storage for the preferences to be send.
*/

View File

@@ -2,40 +2,529 @@
#ifdef Q_OS_UNIX
/*
* System includes
*/
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
/*
* Constructor
*/
WindowCtrl::WindowCtrl(QObject *parent) : QObject(parent)
WindowCtrlUnix::WindowCtrlUnix( QObject *parent ) : QObject( parent )
{
/*
* Initialize
*/
m_tb_window = 0;
m_tb_windows = QList< quint64 >();
/*
* Get the base display and window
*/
m_display = XOpenDisplay( ":0" );
m_screen = 0;
m_root_window = XDefaultRootWindow( m_display );
}
/*
* Handle change in window state
* Get the parent pid of SysTray-X, TB hopefully
*/
void WindowCtrl::slotWindowState( QString state )
qint64 WindowCtrlUnix::getPpid()
{
m_state = state;
emit signalDebugMessage( "Win state: " + state );
return getppid();
}
/*
* Handle show / hide signal
* Find window(s) by title
*/
void WindowCtrl::slotShowHide()
bool WindowCtrlUnix::findWindow( const QString& title )
{
if( m_state == "minimized" )
QList< WindowItem > windows = listXWindows( m_display, m_root_window );
m_tb_windows = QList< quint64 >();
foreach( WindowItem win, windows )
{
m_state = "normal";
emit signalWindowNormal();
} else {
m_state = "minimized";
emit signalWindowMinimize();
char *name = nullptr;
if( XFetchName( m_display, win.window, &name ) > 0 ) {
QString win_name( name );
XFree( name );
if( win_name.contains( title, Qt::CaseInsensitive ) ) {
/*
* Store the XID
*/
m_tb_windows.append( static_cast<quint64>( win.window ) );
}
}
}
if( m_tb_windows.length() > 0 )
{
return true;
}
return false;
}
/*
* Find a window by PID
*/
void WindowCtrlUnix::findWindow( qint64 pid )
{
QList< WindowItem > windows = listXWindows( m_display, m_root_window );
// Get the PID property atom.
Atom atom_PID = XInternAtom( m_display, "_NET_WM_PID", True );
if( atom_PID == None )
{
return;
}
m_tb_window = 0;
foreach( WindowItem win, windows )
{
Atom type;
int format;
unsigned long nItems;
unsigned long bytesAfter;
unsigned char* propPID = nullptr;
if( Success == XGetWindowProperty( m_display, win.window, atom_PID, 0, 1, False, XA_CARDINAL,
&type, &format, &nItems, &bytesAfter, &propPID ) )
{
if( propPID != nullptr )
{
if( pid == *((reinterpret_cast<qint64 *>( propPID ) ) ) )
{
m_tb_window = win.window;
XFree( propPID );
return;
}
XFree( propPID );
}
}
}
}
/*
* Display window atoms
*/
void WindowCtrlUnix::displayWindowElements( const QString& title )
{
QList< WindowItem > windows = listXWindows( m_display, m_root_window );
foreach( WindowItem win, windows )
{
char *name = nullptr;
if( XFetchName( m_display, win.window, &name ) > 0 ) {
QString win_name( name );
XFree( name );
if( win_name.contains( title, Qt::CaseInsensitive ) ) {
emit signalConsole( QString( "Found: Level %1, XID %2, Name %3" ).arg( win.level ).arg( win.window ).arg( win_name ) );
displayWindowElements( win.window );
}
}
}
}
/*
* Display window atoms
*/
void WindowCtrlUnix::displayWindowElements( quint64 window )
{
QString name = atomName( m_display, window );
emit signalConsole( QString( "Atom name: %1" ).arg( name ) );
QStringList types = atomWindowType( m_display, window );
foreach( QString type, types )
{
emit signalConsole( QString( "Atom type: %1" ).arg( type ) );
}
QStringList states = atomState( m_display, window );
bool max_vert = false;
bool max_horz = false;
bool hidden = false;
foreach( QString state, states )
{
emit signalConsole( QString( "Atom state: %1" ).arg( state ) );
int state_code = WindowStates.indexOf( state ) ;
switch( state_code )
{
case STATE_MAXIMIZED_VERT:
{
max_vert = true;
break;
}
case STATE_MAXIMIZED_HORZ:
{
max_horz = true;
break;
}
case STATE_HIDDEN:
{
hidden = true;
break;
}
}
}
if( states.length() > 0 )
{
if( hidden )
{
emit signalConsole( "Window State: Hidden" );
}
else
if( max_vert && max_horz )
{
emit signalConsole( "Window State: Maximize" );
}
else
{
emit signalConsole( "Window State: Normal" );
}
}
else
{
emit signalConsole( "Window State: Normal" );
}
}
/*
* Get the Thunderbird window ID
*/
quint64 WindowCtrlUnix::getWinId()
{
return m_tb_window;
}
/*
* Get the Thunderbird window IDs
*/
QList< quint64 > WindowCtrlUnix::getWinIds()
{
return m_tb_windows;
}
/*
* Minimize a window
*/
void WindowCtrlUnix::minimizeWindow( quint64 window, bool hide )
{
Window win = static_cast<Window>( window );
if( hide )
{
hideWindow( win, hide );
}
XIconifyWindow( m_display, win, m_screen );
XFlush( m_display );
}
/*
* Normalize a window
*/
void WindowCtrlUnix::normalizeWindow( quint64 window )
{
Window win = static_cast<Window>( window );
hideWindow( win, false );
XEvent event = { 0 };
event.xclient.type = ClientMessage;
event.xclient.serial = 0;
event.xclient.send_event = True;
event.xclient.message_type = XInternAtom( m_display, "_NET_ACTIVE_WINDOW", False );
event.xclient.window = static_cast<Window>( window );
event.xclient.format = 32;
XSendEvent( m_display, m_root_window, False, SubstructureRedirectMask | SubstructureNotifyMask, &event );
XMapRaised( m_display, win );
// XMapWindow( m_display, win );
XFlush( m_display );
}
/*
* Remove window from taskbar
*/
void WindowCtrlUnix::hideWindow( quint64 window, bool set )
{
Window win = static_cast<Window>( window );
char prop_name[] = "_NET_WM_STATE";
Atom prop = XInternAtom( m_display, prop_name, True );
Atom prop_skip_taskbar = XInternAtom( m_display, WindowStates[ STATE_SKIP_TASKBAR ].toUtf8(), True );
Atom type;
int format;
unsigned long remain;
unsigned long len;
unsigned char* list = nullptr;
if( XGetWindowProperty( m_display, win, prop, 0, sizeof( Atom ), False, XA_ATOM,
&type, &format, &len, &remain, &list ) == Success )
{
Atom* atom_list = reinterpret_cast<Atom *>( list );
Atom* new_atom_list = nullptr;
bool present = false;
if( len > 1 )
{
/*
* Check and remove atom from list
*/
new_atom_list = new Atom[ len - 1 ];
for( unsigned long i = 0, o = 0; i < len; ++i )
{
if( atom_list[ i ] == prop_skip_taskbar )
{
present = true;
continue;
}
new_atom_list[ o++ ] = atom_list[ i ];
}
}
if( set && !present )
{
/*
* Set the atom
*/
XChangeProperty( m_display, win, prop, XA_ATOM, 32, PropModeAppend,
reinterpret_cast<unsigned char*>( &prop_skip_taskbar ), 1 );
}
else
if( !set && present )
{
/*
* Remove the atom
*/
XChangeProperty( m_display, win, prop, XA_ATOM, format, PropModeReplace,
reinterpret_cast<unsigned char*>( new_atom_list ), static_cast<int>( len - 1 ) );
}
/*
* Cleanup
*/
if( new_atom_list )
{
delete [] new_atom_list;
}
}
/*
* Cleanup
*/
if( list )
{
XFree( list );
}
XFlush( m_display );
}
/*
* Delete the window
*/
void WindowCtrlUnix::deleteWindow( quint64 window )
{
Window win = static_cast<Window>( window );
Atom prop = XInternAtom( m_display, "WM_PROTOCOLS", True );
if( prop == None )
{
return;
}
Atom delete_prop = XInternAtom( m_display, "WM_DELETE_WINDOW", False );
if( prop == None )
{
return;
}
XEvent event;
event.xclient.type = ClientMessage;
event.xclient.window = win;
event.xclient.message_type = prop;
event.xclient.format = 32;
event.xclient.data.l[0] = static_cast<long>( delete_prop );
event.xclient.data.l[1] = CurrentTime;
XSendEvent( m_display, win, False, NoEventMask, &event );
XFlush( m_display );
}
/*
* Get the X11 window list
*/
QList< WindowCtrlUnix::WindowItem > WindowCtrlUnix::listXWindows( Display *display, quint64 window, int level )
{
Window root;
Window parent;
Window *children;
unsigned int childrenCount;
QList< WindowItem > windows;
if( XQueryTree( display, window, &root, &parent, &children, &childrenCount) )
{
for( unsigned int i = 0; i < childrenCount; ++i )
{
windows.append( WindowItem( children[ i ], level ) );
windows.append( listXWindows( display, children[ i ], level + 1) );
}
XFree( children );
}
return windows;
}
/*
* Get the title of the window
*/
QString WindowCtrlUnix::atomName( Display *display, quint64 window )
{
char prop_name[] = "_NET_WM_NAME";
Atom prop = XInternAtom( display, prop_name, True );
Atom utf8_string = XInternAtom( display, "UTF8_STRING", False );
Atom type;
int format;
unsigned long remain;
unsigned long len;
unsigned char* list = nullptr;
QString name;
if( XGetWindowProperty( display, window, prop, 0, LONG_MAX, False, utf8_string,
&type, &format, &len, &remain, &list ) == Success )
{
name = QString( reinterpret_cast<char*>( list ) );
}
if( list )
{
XFree( list );
}
return name;
}
/*
* Get the state of the window
*/
QStringList WindowCtrlUnix::atomState( Display *display, quint64 window )
{
char prop_name[] = "_NET_WM_STATE";
Atom prop = XInternAtom( display, prop_name, True );
Atom type;
int format;
unsigned long remain;
unsigned long len;
unsigned char* list = nullptr;
QStringList states;
// if( XGetWindowProperty( display, window, prop, 0, LONG_MAX, False, AnyPropertyType,
// &type, &format, &len, &remain, &list ) == Success )
if( XGetWindowProperty( display, window, prop, 0, sizeof( Atom ), False, XA_ATOM,
&type, &format, &len, &remain, &list ) == Success )
{
for( unsigned long i = 0; i < len; ++i )
{
char* atom_name = XGetAtomName( display, reinterpret_cast<Atom *>( list )[ i ] );
states.append( atom_name );
if( atom_name )
{
XFree( atom_name );
}
}
}
if( list )
{
XFree( list );
}
return states;
}
/*
* Get the type of the window
*/
QStringList WindowCtrlUnix::atomWindowType( Display *display, quint64 window )
{
char prop_name[] = "_NET_WM_WINDOW_TYPE";
Atom prop = XInternAtom( display, prop_name, True );
Atom type;
int format;
unsigned long remain;
unsigned long len;
unsigned char* list = nullptr;
QStringList states;
if( XGetWindowProperty( display, window, prop, 0, sizeof( Atom ), False, XA_ATOM,
&type, &format, &len, &remain, &list ) == Success )
{
for( unsigned long i = 0; i < len; ++i )
{
char* atom_name = XGetAtomName( display, reinterpret_cast<Atom *>( list )[ i ] );
states.append( atom_name );
if( atom_name )
{
XFree( atom_name );
}
}
}
if( list )
{
XFree( list );
}
return states;
}
#endif // Q_OS_UNIX

View File

@@ -1,65 +1,290 @@
#include <QtGlobal>
#ifdef Q_OS_UNIX
#ifndef WINDOWCTRLLINUX_H
#define WINDOWCTRLLINUX_H
#ifndef WINDOWCTRLUNIX_H
#define WINDOWCTRLUNIX_H
/*
* Local includes
*/
#include "preferences.h"
/*
* System includes
*/
/*
* Qt includes
*/
#include <QObject>
class WindowCtrl : public QObject
/*
* Predefines
*/
typedef struct _XDisplay Display;
/**
* @brief The WindowCtrlUnix class.
*/
class WindowCtrlUnix : public QObject
{
Q_OBJECT
public:
/*
* Window types
*/
enum WindowType
{
TYPE_UNKNOWN = 0,
TYPE_DESKTOP,
TYPE_DOCK,
TYPE_TOOLBAR,
TYPE_MENU,
TYPE_UTILITY,
TYPE_SPLASH,
TYPE_DIALOG,
TYPE_DROPDOWN_MENU,
TYPE_POPUP_MENU,
TYPE_TOOLTIP,
TYPE_NOTIFICATION,
TYPE_COMBO,
TYPE_DND,
TYPE_NORMAL
};
/*
* Window states
*/
enum WindowState
{
STATE_MODAL = 0,
STATE_STICKY,
STATE_MAXIMIZED_VERT,
STATE_MAXIMIZED_HORZ,
STATE_SHADED,
STATE_SKIP_TASKBAR,
STATE_SKIP_PAGER,
STATE_HIDDEN,
STATE_FULLSCREEN,
STATE_ABOVE,
STATE_BELOW,
STATE_DEMANDS_ATTENTION
};
const QStringList WindowStates = {
"_NET_WM_STATE_MODAL",
"_NET_WM_STATE_STICKY",
"_NET_WM_STATE_MAXIMIZED_VERT",
"_NET_WM_STATE_MAXIMIZED_HORZ",
"_NET_WM_STATE_SHADED",
"_NET_WM_STATE_SKIP_TASKBAR",
"_NET_WM_STATE_SKIP_PAGER",
"_NET_WM_STATE_HIDDEN",
"_NET_WM_STATE_FULLSCREEN",
"_NET_WM_STATE_ABOVE",
"_NET_WM_STATE_BELOW",
"_NET_WM_STATE_DEMANDS_ATTENTION"
};
/*
* Window list item
*/
class WindowItem
{
public:
WindowItem( quint64 win, int lev )
{
window = win;
level = lev;
}
quint64 window;
int level;
};
public:
/**
* @brief WindowCtrl. Constructor.
* @brief WindowCtrlUnix. Constructor.
*
* @param parent My parent.
*/
explicit WindowCtrl( QObject *parent = nullptr );
signals:
explicit WindowCtrlUnix( QObject *parent = nullptr );
/**
* @brief signalDebugMessage. Signal a debug message.
* @brief getPpid. Get the parent process id.
*
* @param message The message.
* @return The ppid
*/
void signalDebugMessage( QString message );
qint64 getPpid();
/**
* @brief signalWindowNormal. Signal normal window.
*/
void signalWindowNormal();
/**
* @brief signalWindowMinimuze. Signal minimize window.
*/
void signalWindowMinimize();
public slots:
/**
* @brief slotWindowState. Handle the window state change signal.
* @brief findWindow. Find window by (sub)title.
*
* @param state The new state.
* @param title The title to find.
*
* @return State of the find.
*/
void slotWindowState( QString state );
bool findWindow( const QString& title );
/**
* @brief slotShowHide. Slot for handling of the show / hide window signal.
* @brief findWindow. Find window of a process.
*
* @param pid The process id.
*/
void slotShowHide();
void findWindow( qint64 pid );
/**
* @brief displayWindowElements. Display window elements (atoms).
*
* @param title The window title to find.
*/
void displayWindowElements( const QString& title );
/**
* @brief displayWindowElements. Display window elements (atoms).
*
* @param window The window.
*/
void displayWindowElements( quint64 window );
/**
* @brief getWinId. Get the Thunderbird window ID.
*
* @return The window ID.
*/
quint64 getWinId();
/**
* @brief getWinIds. Get the Thunderbird window IDs.
*
* @return The list of window ID.
*/
QList< quint64 > getWinIds();
/**
* @brief minimizeWindow. Minimize window.
*
* @param window The window.
* @param hide Hide from taskbar.
*/
void minimizeWindow( quint64 window, bool hide );
/**
* @brief normalizeWindow. Normalize window.
*
* @param window The window.
*/
void normalizeWindow( quint64 window );
/**
* @brief hideWindow. Hide a window from the taskbar.
*
* @param window The window.
* @param set The state of the window.
*/
void hideWindow( quint64 window, bool set );
/**
* @brief deleteWindow. Delete the window.
*
* @param window The window.
*/
void deleteWindow( quint64 window );
private:
/**
* @brief m_state. State of the TB window.
* @brief listXWindows. Get all the windows.
*
* @param display The display.
* @param window The window.
* @param level The recursion level.
*
* @return The windows list.
*/
QString m_state;
QList< WindowItem > listXWindows( Display* display, quint64 window, int level = 0 );
/**
* @brief atomwName. Get the title of the window.
*
* @param display The display
* @param window The window
*
* @return Name of the window.
*/
QString atomName( Display* display, quint64 window );
/**
* @brief atomState. Get the state of the window.
*
* @param display The display
* @param window The window
*
* @return State of the window.
*/
QStringList atomState( Display* display, quint64 window );
/**
* @brief atomType. Get the type of the window.
*
* @param display The display
* @param window The window
*
* @return Type of the window.
*/
QStringList atomWindowType( Display* display, quint64 window );
signals:
/**
* @brief signalWindowNormal. Signal normal window.
*/
void signalWindowNormal();
/**
* @brief signalWindowMinimuze. Signal minimize window.
*/
void signalWindowMinimize();
/**
* @brief signalConsole. Send a console message.
*
* @param message The message.
*/
void signalConsole( QString message );
private:
/**
* @brief m_display. Pointer to the main display.
*/
Display* m_display;
/**
* @brief m_screen. The screen number.
*/
int m_screen;
/**
* @brief m_root_window. The root window.
*/
quint64 m_root_window;
/**
* @brief m_tb_window. The Thunderbird window.
*/
quint64 m_tb_window;
/**
* @brief m_tb_windows. The Thunderbird windows (used by title search).
*/
QList< quint64 > m_tb_windows;
};
#endif // WINDOWCTRLLINUX_H
#endif // WINDOWCTRLUNIX_H
#endif // Q_OS_UNIX

View File

@@ -2,39 +2,254 @@
#ifdef Q_OS_WIN
/*
* System includes
*/
#include <tlhelp32.h>
#include <CommCtrl.h>
/*
* Qt includes
*/
#include <QCoreApplication>
/*
* Statics
*/
quint64 WindowCtrlWin::m_tb_window;
QList< quint64 > WindowCtrlWin::m_tb_windows;
/*
* Constructor
*/
WindowCtrl::WindowCtrl(QObject *parent) : QObject(parent)
WindowCtrlWin::WindowCtrlWin( QObject *parent) : QObject( parent )
{
/*
* Initialize
*/
m_tb_window = 0;
m_tb_windows = QList< quint64 >();
}
/*
* Handle change in window state
* Get the parent pid of SysTray-X, TB hopefully
*/
void WindowCtrl::slotWindowState( QString state )
qint64 WindowCtrlWin::getPpid()
{
m_state = state;
HANDLE h = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
PROCESSENTRY32 pe;
pe.dwSize = sizeof( PROCESSENTRY32 );
emit signalDebugMessage( "Win state: " + state );
}
qint64 ppid = -1;
qint64 pid = QCoreApplication::applicationPid();
/*
* Handle show / hide signal
*/
void WindowCtrl::slotShowHide()
{
if( m_state == "minimized" )
if( Process32First( h, &pe ) )
{
m_state = "normal";
emit signalWindowNormal();
} else {
m_state = "minimized";
emit signalWindowMinimize();
do
{
if( pe.th32ProcessID == pid )
{
ppid = pe.th32ParentProcessID;
break;
}
}
while( Process32Next( h, &pe ) );
}
CloseHandle( h );
return ppid;
}
/*
* Find the window by title
*/
bool WindowCtrlWin::findWindow( const QString& title )
{
m_tb_windows = QList< quint64 >();
EnumWindows( &enumWindowsTitleProc, (LPARAM)(LPSTR)( title.toStdString().c_str() ) );
if( m_tb_windows.length() == 0 )
{
return false;
}
return true;
}
/*
* Callback for the window enumaration title find.
*/
BOOL CALLBACK WindowCtrlWin::enumWindowsTitleProc( HWND hwnd, LPARAM lParam )
{
char buffer[ 128 ];
int written = GetWindowTextA( hwnd, buffer, 128 );
if( written && strstr( buffer, (char*)lParam ) != NULL )
{
m_tb_windows.append( (quint64)hwnd );
}
return TRUE;
}
/*
* Find the window by pid
*/
bool WindowCtrlWin::findWindow( qint64 pid )
{
HandleData data;
data.pid = pid;
data.hwnd = 0;
EnumWindows( &enumWindowsPidProc, (LPARAM)&data );
if( data.hwnd == 0 )
{
return false;
}
/*
* Store it
*/
m_tb_window = (quint64)data.hwnd;
return true;
}
/*
* Callback for the window enumaration pid find.
*/
BOOL CALLBACK WindowCtrlWin::enumWindowsPidProc( HWND hwnd, LPARAM lParam )
{
HandleData& data = *(HandleData*)lParam;
unsigned long pid = 0;
GetWindowThreadProcessId( hwnd, &pid );
if( data.pid != pid || !isMainWindow( hwnd ) )
{
return TRUE;
}
data.hwnd = hwnd;
return FALSE;
}
/*
* Check for main window
*/
BOOL WindowCtrlWin::isMainWindow( HWND hwnd )
{
return GetWindow( hwnd, GW_OWNER ) == (HWND)0 && IsWindowVisible( hwnd );
}
/*
* Display the window elements
*/
void WindowCtrlWin::displayWindowElements( const QString& title )
{
findWindow( title );
foreach( quint64 win_id, getWinIds() )
{
emit signalConsole( QString( "Found: XID %1" ).arg( win_id ) );
}
}
/*
* Display the window elements
*/
void WindowCtrlWin::displayWindowElements( quint64 window )
{
emit signalConsole( QString( "Found: XID %1" ).arg( window ) );
}
/*
* Get the Thunderbird window ID
*/
quint64 WindowCtrlWin::getWinId()
{
return m_tb_window;
}
/*
* Get the Thunderbird window IDs
*/
QList< quint64 > WindowCtrlWin::getWinIds()
{
return m_tb_windows;
}
/*
* Minimize a window
*/
void WindowCtrlWin::minimizeWindow( quint64 window, bool hide )
{
ShowWindow( (HWND)window, SW_MINIMIZE );
if( hide )
{
hideWindow( (HWND)window );
}
}
/*
* Normalize a window
*/
void WindowCtrlWin::normalizeWindow( quint64 window )
{
ShowWindow( (HWND)window, SW_RESTORE );
SetForegroundWindow( (HWND)window );
}
/*
* Hide a window
*/
void WindowCtrlWin::hideWindow( quint64 window, bool state )
{
if( state )
{
hideWindow( (HWND)window );
}
}
/*
* Hide a window
*/
void WindowCtrlWin::hideWindow( HWND hwnd )
{
long style = GetWindowLong( hwnd, GWL_STYLE );
style &= ~(WS_VISIBLE);
style |= WS_EX_TOOLWINDOW;
style &= ~(WS_EX_APPWINDOW);
SetWindowLong( hwnd, GWL_STYLE, style );
}
/*
* Delete / Close a window
*/
void WindowCtrlWin::deleteWindow( quint64 window )
{
SendMessageA( (HWND)window, WM_CLOSE, 0, 0 );
}
#endif // Q_OS_WIN

View File

@@ -4,20 +4,160 @@
#ifndef WINDOWCTRLWIN_H
#define WINDOWCTRLWIN_H
/*
* System includes
*/
#include <Windows.h>
/*
* Qt includes
*/
#include <QObject>
class WindowCtrl : public QObject
/**
* @brief The WindowCtrlWin class
*/
class WindowCtrlWin : public QObject
{
Q_OBJECT
private:
struct HandleData
{
unsigned long pid;
HWND hwnd;
};
public:
/**
* @brief WindowCtrl. Constructor.
* @brief WindowCtrlWin. Constructor.
*
* @param parent My parent.
*/
explicit WindowCtrl( QObject *parent = nullptr );
explicit WindowCtrlWin( QObject *parent = nullptr );
/**
* @brief getPpid. Get the parent process id.
*
* @return The ppid
*/
qint64 getPpid();
/**
* @brief findWindow. Find window by title.
*
* @param title The (part)title to find.
*
* @return State of the find.
*/
bool findWindow( const QString& title );
/**
* @brief findWindow. Find window by pid.
*
* @param pid The pid to find.
*
* @return State of the find.
*/
bool findWindow( qint64 pid );
/**
* @brief displayWindowElements. Display window elements.
*
* @param title The title to find.
*/
void displayWindowElements( const QString& title );
/**
* @brief displayWindowElements. Display window elements.
*
* @param title The window id.
*/
void displayWindowElements( quint64 window );
/**
* @brief getWinId. Get the Thunderbird window ID.
*
* @return The TB window ID.
*/
quint64 getWinId();
/**
* @brief getWinIds. Get the Thunderbird window IDs.
*
* @return The list of window IDs.
*/
QList< quint64 > getWinIds();
/**
* @brief minimizeWindow. Minimize window.
*
* @param window The window.
* @param hide Hide from taskbar
*/
void minimizeWindow( quint64 window, bool hide );
/**
* @brief normalizeWindow. Normalize window.
*
* @param window The window.
*/
void normalizeWindow( quint64 window );
/**
* @brief WindowCtrlWin::hideWindow
*
* @param window The window.
* @param state Hide from taskbar.
*/
void hideWindow( quint64 window , bool state );
/**
* @brief deleteWindow. Delete window.
*
* @param window The window.
*/
void deleteWindow( quint64 window );
private:
/**
* @brief hideWindow. Hide window.
*
* @param hwnd The window.
*/
void hideWindow( HWND hwnd );
/**
* @brief EnumWindowsTitleProc. Callback for window enumaration by title.
*
* @param hwnd Handle of window.
* @param lParam Argument passed by EnumWindows.
*
* @return State of callback. (TRUE = continue / FALSE = stop)
*/
static BOOL CALLBACK enumWindowsTitleProc( HWND hwnd, LPARAM lParam );
/**
* @brief EnumWindowsPidProc. Callback for window enumaration by pid.
*
* @param hwnd Handle of window.
* @param lParam Argument passed by EnumWindows.
*
* @return State of callback. (TRUE = continue / FALSE = stop)
*/
static BOOL CALLBACK enumWindowsPidProc( HWND hwnd, LPARAM lParam );
/**
* @brief isMainWindow. Check for main window.
*
* @param hwnd The window handle.
*
* @return Result of the check.
*/
static BOOL isMainWindow( HWND hwnd );
signals:
@@ -38,26 +178,24 @@ class WindowCtrl : public QObject
*/
void signalWindowMinimize();
public slots:
/**
* @brief slotWindowState. Handle the window state change signal.
* @brief signalConsole. Send a console message.
*
* @param state The new state.
* @param message The message.
*/
void slotWindowState( QString state );
/**
* @brief slotShowHide. Slot for handling of the show / hide window signal.
*/
void slotShowHide();
void signalConsole( QString message );
private:
/**
* @brief m_state. State of the TB window.
* @brief m_tb_window. The Thunderbird window.
*/
QString m_state;
static quint64 m_tb_window;
/**
* @brief m_tb_window. The Thunderbird windows.
*/
static QList< quint64 > m_tb_windows;
};
#endif // WINDOWCTRLWIN_H

View File

@@ -0,0 +1,174 @@
/*
* Qt includes
*/
#include <QWidget>
#include <QWindow>
#include <QCoreApplication>
/*
* Main include
*/
#include "windowctrl.h"
/*
* System includes
*/
#include "preferences.h"
/*
* Constructor
*/
WindowCtrl::WindowCtrl( Preferences* pref, QObject *parent )
#ifdef Q_OS_UNIX
: WindowCtrlUnix( parent )
#elif defined Q_OS_WIN
: WindowCtrlWin( parent )
#else
: public QObject
#endif
{
/*
* Store preferences
*/
m_pref = pref;
/*
* Initialize
*/
m_hide_minimize = m_pref->getHideOnMinimize();
/*
* Get pids
*/
m_pid = QCoreApplication::applicationPid();
m_ppid = getPpid();
/*
* Get the TB window
*/
findWindow( m_ppid );
}
void WindowCtrl::slotWindowTest1()
{
emit signalConsole("Test 1 started");
// Do something.
// findWindow( "- Mozilla Thunderbird" );
// displayWindowElements( "- Mozilla Thunderbird" );
// findWindow( 4313 );
// displayWindowElements( getWinId() );
emit signalConsole("Test 1 done");
}
void WindowCtrl::slotWindowTest2()
{
emit signalConsole("Test 2 started");
// Do something.
// findWindow( m_ppid );
// emit signalConsole( QString( "Hwnd ppid: %1" ).arg( getWinIds()[0] ) );
emit signalConsole("Test 2 done");
}
void WindowCtrl::slotWindowTest3()
{
emit signalConsole("Test 3 started");
// Do something.
// emit signalConsole( QString( "Pid %1" ).arg( m_pid ) );
// emit signalConsole( QString( "Ppid %1" ).arg( m_ppid ) );
emit signalConsole("Test 3 done");
}
/*
* Handle window title signal
*/
void WindowCtrl::slotWindowTitle( QString title )
{
/*
* Store the window title
*/
m_window_title = title;
/*
* Get the window IDs
*/
findWindow( title );
}
/*
* Handle change in hide on minimize state
*/
void WindowCtrl::slotHideOnMinimizeChange()
{
m_hide_minimize = m_pref->getHideOnMinimize();
}
/*
* Handle change in start minimized state
*/
void WindowCtrl::slotStartMinimizedChange()
{
m_start_minimized = m_pref->getStartMinimized();
}
/*
* Handle change in window state
*/
void WindowCtrl::slotWindowState( QString state )
{
if( m_state != state )
{
m_state = state;
if( state == "normal" )
{
hideWindow( getWinId(), false );
}
else
{
hideWindow( getWinId(), m_hide_minimize );
}
}
}
/*
* Handle show / hide signal
*/
void WindowCtrl::slotShowHide()
{
if( m_state == "minimized" )
{
m_state = "normal";
normalizeWindow( getWinId() );
}
else
{
m_state = "minimized";
minimizeWindow( getWinId(), m_hide_minimize );
}
}
/*
* Handle close signal
*/
void WindowCtrl::slotClose()
{
deleteWindow( getWinId() );
}

View File

@@ -11,4 +11,132 @@
#include "windowctrl-win.h"
#endif // Q_OS_WIN
/*
* Predefines
*/
class QWindow;
class Preferences;
/**
* @brief The WindowCtrl class.
*/
#ifdef Q_OS_UNIX
class WindowCtrl : public WindowCtrlUnix
#elif defined Q_OS_WIN
class WindowCtrl : public WindowCtrlWin
#else
class WindowCtrl : public QObject
#endif
{
Q_OBJECT
public:
/**
* @brief WindowCtrlUnix. Constructor.
*
* @param parent My parent.
*/
explicit WindowCtrl( Preferences* pref, QObject *parent = nullptr );
public slots:
/**
* @brief slotWindowTest1. Start a test.
*/
void slotWindowTest1();
/**
* @brief slotWindowTest2. Start a test.
*/
void slotWindowTest2();
/**
* @brief slotWindowTest3. Start a test.
*/
void slotWindowTest3();
/**
* @brief slotWindowTitle. Handle the window title signal.
*
* @param state The windows title.
*/
void slotWindowTitle( QString title );
/**
* @brief slotHideOnMinimizeChange. Handle the hide on minimize signal.
*
* @param state The state
*/
void slotHideOnMinimizeChange();
/**
* @brief slotStartMinimizedChange. Handle the start minimized signal.
*
* @param state The state
*/
void slotStartMinimizedChange();
/**
* @brief slotWindowState. Handle the window state change signal.
*
* @param state The new state.
*/
void slotWindowState( QString state );
/**
* @brief slotShowHide. Slot for handling of the show / hide window signal.
*/
void slotShowHide();
/**
* @brief slotClose.
*/
void slotClose();
private:
/**
* @brief m_pref. Pointer to the preferences storage.
*/
Preferences* m_pref;
/**
* @brief m_pid. SysTray-X process pid.
*/
qint64 m_pid;
/**
* @brief m_ppid. SysTray-X parent process pid.
*/
qint64 m_ppid;
/**
* @brief m_tb_window. Pointer to the TB window.
*/
QWindow* m_tb_window;
/**
* @brief m_window_title. Title of the TB window.
*/
QString m_window_title;
/**
* @brief m_hide_minimize. State of hide on minimize.
*/
bool m_hide_minimize;
/**
* @brief m_start_minimized. State of start minimized.
*/
bool m_start_minimized;
/**
* @brief m_state. State of the TB window.
*/
QString m_state;
};
#endif // WINDOWCTRL_H

1
app/config/linux/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.json

1
app/config/win32/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.json

View File

@@ -1,26 +1,31 @@
{
"extensionName": {
"extension_name": {
"message": "SysTray-X",
"description": "Name of the webextension"
},
"extensionDescription": {
"extension_description": {
"message": "System tray control add-on",
"description": "Webextension descriptions"
},
"tabWindows": {
"tab_windows": {
"message": "Windows",
"description": "Tab for Window options"
},
"tabIcon": {
"tab_icon": {
"message": "Icon",
"description": "Tab for Icon options"
},
"tabMail": {
"tab_mail": {
"message": "Mail",
"description": "Tab for Mail options"
},
"tab_debug": {
"message": "Debug",
"description": "Tab for Debug options"
}
}

View File

@@ -10,7 +10,7 @@
<p>Background HTML</p>
<div id="accounts" data-accounts="[]">
<div id="filters" data-filters="[]"></div>
<div id="filters" data-filters=undefined></div>
</div>
<script src="js/defaults.js"></script>

View File

@@ -1,5 +1,3 @@
console.log("Starting background.js");
var SysTrayX = {
debugAccounts: false
};
@@ -11,17 +9,18 @@ SysTrayX.Messaging = {
],
init: function() {
console.log("Enabling Messaging");
// Get the accounts from the storage
SysTrayX.Messaging.getAccounts();
browser.storage.onChanged.addListener(SysTrayX.Messaging.storageChanged);
// Send the window title to app
SysTrayX.Messaging.sendTitle();
// Send preferences to app
SysTrayX.Messaging.sendPreferences();
// this.unReadMessages(this.unreadFiltersTest).then(this.unreadCb);
window.setInterval(SysTrayX.Messaging.pollAccounts, 10000);
window.setInterval(SysTrayX.Messaging.pollAccounts, 1000);
// Send the app a close command if the window closes
browser.windows.onRemoved.addListener(SysTrayX.Window.closed);
@@ -34,14 +33,10 @@ SysTrayX.Messaging = {
// Handle a storage change
//
storageChanged: function(changes, area) {
console.debug("Changes in store");
// Get the new preferences
SysTrayX.Messaging.getAccounts();
if ("addonprefchanged" in changes && changes["addonprefchanged"].newValue) {
console.debug("Sending preference");
//
// Send new preferences to the app
//
@@ -52,36 +47,28 @@ SysTrayX.Messaging = {
addonprefchanged: false
});
}
/*
var changedItems = Object.keys(changes);
for (var item of changedItems) {
console.log(item + " has changed:");
console.log("Old value: ");
console.log(changes[item].oldValue);
console.log("New value: ");
console.log(changes[item].newValue);
}
*/
},
//
// Poll the accounts
//
pollAccounts: function() {
console.debug("Polling");
//
// Get the unread nessages of the selected accounts
//
const filtersDiv = document.getElementById("filters");
const filtersAttr = filtersDiv.getAttribute("data-filters");
const filters = JSON.parse(filtersAttr);
if (filters.length > 0) {
SysTrayX.Messaging.unReadMessages(filters).then(
SysTrayX.Messaging.unreadCb
);
if (filtersAttr !== "undefined") {
const filters = JSON.parse(filtersAttr);
if (filters.length > 0) {
SysTrayX.Messaging.unReadMessages(filters).then(
SysTrayX.Messaging.unreadCb
);
} else {
SysTrayX.Link.postSysTrayXMessage({ unreadMail: 0 });
}
} else {
SysTrayX.Messaging.unReadMessages([{ unread: true }]).then(
SysTrayX.Messaging.unreadCb
@@ -118,11 +105,16 @@ SysTrayX.Messaging = {
SysTrayX.Link.postSysTrayXMessage({ unreadMail: count });
},
sendPreferences: function() {
console.debug("Send preferences");
sendTitle: function() {
const title = "-" + SysTrayX.Window.startWindow.title.split("-").pop();
SysTrayX.Link.postSysTrayXMessage({ title: title });
},
sendPreferences: function() {
const getter = browser.storage.sync.get([
"debug",
"hideOnMinimize",
"startMinimized",
"iconType",
"iconMime",
"icon"
@@ -131,22 +123,19 @@ SysTrayX.Messaging = {
},
sendPreferencesStorage: function(result) {
console.debug("Get preferences from storage");
const debug = result.debug || "false";
const hideOnMinimize = result.hideOnMinimize || "true";
const startMinimized = result.startMinimized || "false";
const iconType = result.iconType || "0";
const iconMime = result.iconMime || "image/png";
const icon = result.icon || [];
console.log(`Debug ${debug}`);
console.log(`Type ${iconType}`);
console.log(`Mime ${iconMime}`);
console.log(icon);
// Send it to the app
SysTrayX.Link.postSysTrayXMessage({
preferences: {
debug: debug,
hideOnMinimize: hideOnMinimize,
startMinimized: startMinimized,
iconType: iconType,
iconMime: iconMime,
icon: icon
@@ -162,8 +151,6 @@ SysTrayX.Messaging = {
// Get the accounts from the storage
//
getAccounts: function() {
console.debug("Get accounts");
const getter = browser.storage.sync.get(["accounts", "filters"]);
getter.then(this.getAccountsStorage, this.onGetAccountsStorageError);
@@ -183,15 +170,13 @@ SysTrayX.Messaging = {
// make them available in the background HTML
//
getAccountsStorage: function(result) {
console.debug("Get accounts from storage");
const accounts = result.accounts || [];
const accounts = result.accounts || undefined;
// Store them in the background HTML
const accountsDiv = document.getElementById("accounts");
accountsDiv.setAttribute("data-accounts", JSON.stringify(accounts));
const filters = result.filters || [];
const filters = result.filters || undefined;
// Store them in the background HTML
const filtersDiv = document.getElementById("filters");
@@ -225,11 +210,7 @@ SysTrayX.Link = {
},
receiveSysTrayXMessage: function(response) {
console.log(`Received: ${response}`);
if (response["window"]) {
console.log("Window received: " + response["window"]);
if (response["window"] === "minimized") {
browser.windows.update(SysTrayX.Window.startWindow.id, {
state: "minimized"
@@ -244,10 +225,12 @@ SysTrayX.Link = {
}
}
if (response["shutdown"]) {
console.log("Shutdown received: " + response["shutdown"]);
}
if (response["preferences"]) {
// Store the preferences from the app
console.log("Preferences received");
const iconMime = response["preferences"].iconMime;
if (iconMime) {
browser.storage.sync.set({
@@ -269,6 +252,20 @@ SysTrayX.Link = {
});
}
const hideOnMinimize = response["preferences"].hideOnMinimize;
if (hideOnMinimize) {
browser.storage.sync.set({
hideOnMinimize: hideOnMinimize
});
}
const startMinimized = response["preferences"].startMinimized;
if (startMinimized) {
browser.storage.sync.set({
startMinimized: startMinimized
});
}
const debug = response["preferences"].debug;
if (debug) {
browser.storage.sync.set({
@@ -282,60 +279,42 @@ SysTrayX.Link = {
SysTrayX.Window = {
startWindow: undefined,
closed: function() {
// Window closed
console.debug("Shutting down");
closed: function(windowId) {
// Window closed
// Send it to the app
SysTrayX.Link.postSysTrayXMessage({
shutdown: ""
});
SysTrayX.Link.postSysTrayXMessage({ shutdown: "true" });
},
focusChanged: function(windowId) {
console.debug("Win focus changed");
browser.windows.getCurrent().then(win => {
SysTrayX.Link.postSysTrayXMessage({ window: win.state });
});
/*
if (windowId === -1) {
// Assume minimized
SysTrayX.Link.postSysTrayXMessage({
window: "minimized"
});
} else {
browser.windows.get(windowId, function(win) {
SysTrayX.Link.postSysTrayXMessage({
window: win.state
});
});
}
*/
}
};
async function start() {
// Init defaults before everything
// Get the prefered start state
const state = await getStartupState();
if (state == "minimized") {
browser.windows.update(browser.windows.WINDOW_ID_CURRENT, {
state: "minimized"
});
}
// Init defaults before everything
await getDefaultIcon();
SysTrayX.Window.startWindow = await browser.windows
.getCurrent()
.then(currentWindow => currentWindow);
console.debug("Window focus: " + SysTrayX.Window.startWindow.focused);
console.debug("Window name: " + SysTrayX.Window.startWindow.title);
console.debug("Window name: " + SysTrayX.Window.startWindow.state);
// browser.windows.update(currentWindow.id, { state: "minimized" });
// browser.windows.update(currentWindow.id, { state: "normal", focused: true });
// ?? browser.windows.update(currentWindow.id, { state: "docked" });
// Setup the link first
SysTrayX.Link.init();
// Send current state
SysTrayX.Link.postSysTrayXMessage({ window: state });
// Main start
SysTrayX.Messaging.init();
}
@@ -344,5 +323,3 @@ console.log("Starting SysTray-X");
// Start the add-on
start();
console.log("End SysTray-X");

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -49,8 +49,21 @@ async function getDefaultIcon() {
const iconDiv = document.getElementById("icon");
iconDiv.setAttribute("data-icon-mime", iconMime);
iconDiv.setAttribute("data-icon", iconBase64);
console.debug("Default: " + iconMime);
console.debug("Default: " + iconBase64);
}
}
//
// Get window startup state
//
async function getStartupState() {
function getStartupState(result) {
return result.startMinimized == "true" ? "minimized" : "normal";
}
function onStartupStateError() {
return "normal";
}
const getState = browser.storage.sync.get("startMinimized");
return await getState.then(getStartupState, onStartupStateError);
}

View File

@@ -22,9 +22,9 @@ SysTrayX.Accounts = {
let accounts = new Object();
for (let i = 0; i < mailAccount.length; i++) {
console.debug("SysTrayX accounts id: " + mailAccount[i].id);
console.debug("SysTrayX accounts name: " + mailAccount[i].name);
console.debug("SysTrayX accounts type: " + mailAccount[i].type);
// console.debug("SysTrayX accounts id: " + mailAccount[i].id);
// console.debug("SysTrayX accounts name: " + mailAccount[i].name);
// console.debug("SysTrayX accounts type: " + mailAccount[i].type);
if (!accounts[mailAccount[i].type]) {
accounts[mailAccount[i].type] = [];
@@ -66,7 +66,9 @@ SysTrayX.Accounts = {
typeInput.setAttribute("value", JSON.stringify(accounts[prop][i]));
typeInput.setAttribute("checked", "true");
typeLi.appendChild(typeInput);
const typeText = document.createTextNode(" " + accounts[prop][i].name);
const typeText = document.createTextNode(
" " + accounts[prop][i].name
);
typeLi.appendChild(typeText);
typeUl.appendChild(typeLi);
}
@@ -77,8 +79,6 @@ SysTrayX.Accounts = {
// Restore saved selection
function setAccounts(result) {
console.debug("Restore account selection");
const treeBase = document.getElementById("accountsTree");
const accounts = result.accounts || [];
for (let i = 0; i < accounts.length; ++i) {
@@ -89,8 +89,6 @@ SysTrayX.Accounts = {
checkbox.checked = accounts[i].checked;
}
}
console.debug("Restore account selection done");
}
function onError(error) {

View File

@@ -1,10 +1,10 @@
function fileSelected() {
const input = document.getElementById("selectedFileIconType");
if (input.files.length > 0) {
console.debug("Selected file: " + input.files[0].name);
console.debug("Selected file type: " + input.files[0].type);
}
// if (input.files.length > 0) {
// console.debug("Selected file: " + input.files[0].name);
// console.debug("Selected file type: " + input.files[0].type);
// }
function storeFile() {
const buffer = new Uint8Array(fr.result);
@@ -21,9 +21,7 @@ function fileSelected() {
iconDiv.setAttribute("data-icon-mime", input.files[0].type);
const image = document.getElementById("customIconImage");
image.setAttribute("src", `data:${input.files[0].type};base64,${base64}` );
console.log(base64);
image.setAttribute("src", `data:${input.files[0].type};base64,${base64}`);
}
fr = new FileReader();

View File

@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "__MSG_extensionName__",
"description": "__MSG_extensionDescription__",
"name": "__MSG_extension_name__",
"description": "__MSG_extension_description__",
"version": "0.1",
"author": "Maxime Rijnders",
"homepage_url": "https://github.com/Ximi1970/systray-x",

View File

@@ -9,33 +9,20 @@
<script src="js/i18n.js"></script>
<script src="js/options_accounts.js"></script>
<br />
<div id="debugselect">
<input type="checkbox" name="debug" value="Debug" /> Display debug
window<br />
</div>
<br />
<div class="tab">
<button class="tablinks active" id="Windows">__MSG_tabWindows__</button>
<button class="tablinks" id="Icon">__MSG_tabIcon__</button>
<button class="tablinks" id="Mail">__MSG_tabMail__</button>
<button class="tablinks active" id="Windows">__MSG_tab_windows__</button>
<button class="tablinks" id="Icon">__MSG_tab_icon__</button>
<button class="tablinks" id="Mail">__MSG_tab_mail__</button>
<button class="tablinks" id="Debug">__MSG_tab_debug__</button>
</div>
<div id="WindowsContent" class="tabcontent" style="display:block">
<form>
<h3>Windows</h3>
<p>Windows options here</p>
<p>Please select your option:</p>
<input type="radio" name="options_test" value="Option1" /> Option 1<br />
<input type="radio" name="options_test" value="Option2" /> Option 2<br />
<input type="radio" name="options_test" value="Option3" /> Option 3<br />
<p>Please check the boxes:</p>
<input type="checkbox" name="check1" value="Check1" /> Check 1<br />
<input type="checkbox" name="check2" value="Check2" /> Check 2<br />
<input type="checkbox" name="check3" value="Check3" /> Check 3<br />
<input type="checkbox" name="hideOnMinimize" value="" /> Minimizing
window hides to tray<br />
<input type="checkbox" name="startMinimized" value="" /> Start
application minimized<br />
</form>
</div>
@@ -96,6 +83,18 @@
</form>
</div>
<div id="DebugContent" class="tabcontent">
<form name="debugform">
<h3>Debug options</h3>
<br />
<div id="debugselect">
<input type="checkbox" name="debug" value="Debug" /> Display debug
window<br />
</div>
<br />
</form>
</div>
<br />
<form name="saveform">
<label>Save preferences</label>

View File

@@ -4,23 +4,9 @@ SysTrayX.SaveOptions = {
start: function(e) {
e.preventDefault();
console.debug("Save preferences");
browser.storage.sync.set({
optionsRadioTest: document.querySelector(
'input[name="options_test"]:checked'
).value,
optionsCheck1: document.querySelector('input[name="check1"]').checked,
optionsCheck2: document.querySelector('input[name="check2"]').checked,
optionsCheck3: document.querySelector('input[name="check3"]').checked
});
//
// Save accounts and filters
//
console.debug("Store accounts and filters");
const treeBase = document.getElementById("accountsTree");
const inputs = treeBase.querySelectorAll("input");
let accounts = [];
@@ -34,9 +20,6 @@ SysTrayX.SaveOptions = {
let inboxMailFolder = account.folders.find(obj => obj.type === "inbox");
if (inboxMailFolder) {
console.debug("Filter Id: " + inboxMailFolder.accountId);
console.debug("Filter Path: " + inboxMailFolder.path);
filters.push({
unread: true,
folder: inboxMailFolder
@@ -55,8 +38,6 @@ SysTrayX.SaveOptions = {
filters: filters
});
console.debug("Store accounts and filters done");
//
// Save debug state
//
@@ -64,14 +45,28 @@ SysTrayX.SaveOptions = {
browser.storage.sync.set({
debug: `${debug}`
});
console.debug("Store debug state: " + `${debug}`);
//
// Save hide on minimize state
//
let hideOnMinimize = document.querySelector('input[name="hideOnMinimize"]')
.checked;
browser.storage.sync.set({
hideOnMinimize: `${hideOnMinimize}`
});
//
// Save start minimized state
//
let startMinimized = document.querySelector('input[name="startMinimized"]')
.checked;
browser.storage.sync.set({
startMinimized: `${startMinimized}`
});
//
// Save icon preferences
//
console.debug("Store icon preferences");
const iconType = document.querySelector('input[name="iconType"]:checked')
.value;
@@ -90,8 +85,6 @@ SysTrayX.SaveOptions = {
icon: iconBase64
});
console.debug("Store icon preferences done");
// Mark add-on preferences changed
browser.storage.sync.set({
addonprefchanged: true
@@ -101,32 +94,6 @@ SysTrayX.SaveOptions = {
SysTrayX.RestoreOptions = {
start: function() {
console.debug("Restore preferences");
//
// Test 1
//
const getRadioTest = browser.storage.sync.get("optionsRadioTest");
getRadioTest.then(
SysTrayX.RestoreOptions.setCurrentRadioChoice,
SysTrayX.RestoreOptions.onError
);
//
// Test 2
//
const getCheckTest = browser.storage.sync.get([
"optionsCheck1",
"optionsCheck2",
"optionsCheck3"
]);
getCheckTest.then(
SysTrayX.RestoreOptions.setCurrentCheckChoice,
SysTrayX.RestoreOptions.onError
);
console.debug("Restore icon preferences");
//
// Restore debug state
//
@@ -136,6 +103,24 @@ SysTrayX.RestoreOptions = {
SysTrayX.RestoreOptions.onDebugError
);
//
// Restore hide on minimize
//
const getHideOnMinimize = browser.storage.sync.get("hideOnMinimize");
getHideOnMinimize.then(
SysTrayX.RestoreOptions.setHideOnMinimize,
SysTrayX.RestoreOptions.onHideOnMinimizeError
);
//
// Restore start minimized
//
const getStartMinimized = browser.storage.sync.get("startMinimized");
getStartMinimized.then(
SysTrayX.RestoreOptions.setStartMinimized,
SysTrayX.RestoreOptions.onStartMinimizedError
);
//
// Restore icon type
//
@@ -153,36 +138,6 @@ SysTrayX.RestoreOptions = {
SysTrayX.RestoreOptions.setIcon,
SysTrayX.RestoreOptions.onIconError
);
console.debug("Restore icon preferences done");
},
//
// Test 1 Callback
//
setCurrentRadioChoice: function(result) {
const selector = result.optionsRadioTest || "Option1";
const radioButton = document.querySelector(`[value=${selector}]`);
radioButton.checked = true;
},
//
// Test 2 Callback
//
setCurrentCheckChoice: function(result) {
const checkbox1 = document.querySelector('[name="check1"]');
checkbox1.checked = result.optionsCheck1 || false;
const checkbox2 = document.querySelector('[name="check2"]');
checkbox2.checked = result.optionsCheck2 || false;
const checkbox3 = document.querySelector('[name="check3"]');
checkbox3.checked = result.optionsCheck3 || false;
},
//
// Test 1+2 error callback
//
onError: function(error) {
console.log(`Error: ${error}`);
},
//
@@ -191,8 +146,6 @@ SysTrayX.RestoreOptions = {
setDebug: function(result) {
const debug = result.debug || "false";
console.debug("Debug: " + debug);
const checkbox = document.querySelector(`input[name="debug"]`);
checkbox.checked = debug === "true";
},
@@ -201,6 +154,34 @@ SysTrayX.RestoreOptions = {
console.log(`Debug Error: ${error}`);
},
//
// Restore hide on minimize callbacks
//
setHideOnMinimize: function(result) {
const hideOnMinimize = result.hideOnMinimize || "true";
const checkbox = document.querySelector(`input[name="hideOnMinimize"]`);
checkbox.checked = hideOnMinimize === "true";
},
onHideOnMinimizeError: function(error) {
console.log(`hideOnMinimize Error: ${error}`);
},
//
// Restore hide on minimize callbacks
//
setStartMinimized: function(result) {
const startMinimized = result.startMinimized || "false";
const checkbox = document.querySelector(`input[name="startMinimized"]`);
checkbox.checked = startMinimized === "true";
},
onStartMinimizedError: function(error) {
console.log(`startMinimized Error: ${error}`);
},
//
// Restore icon type callbacks
//
@@ -287,6 +268,16 @@ SysTrayX.StorageChanged = {
});
changed_icon_mime = true;
}
if (item === "hideOnMinimize") {
SysTrayX.RestoreOptions.setHideOnMinimize({
hideOnMinimize: changes[item].newValue
});
}
if (item === "startMinimized") {
SysTrayX.RestoreOptions.setStartMinimized({
startMinimized: changes[item].newValue
});
}
if (item === "debug") {
SysTrayX.RestoreOptions.setDebug({
debug: changes[item].newValue