mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-14 01:02:59 -07:00
Add update check to Windows tray icon
This commit is contained in:
parent
5d82ed9415
commit
84ef02aa03
7 changed files with 76 additions and 15 deletions
Binary file not shown.
Before Width: | Height: | Size: 118 KiB |
BIN
data/interfaces/default/images/logo_tray-update.ico
Normal file
BIN
data/interfaces/default/images/logo_tray-update.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 112 KiB |
BIN
data/interfaces/default/images/logo_tray.ico
Normal file
BIN
data/interfaces/default/images/logo_tray.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 107 KiB |
|
@ -38,7 +38,7 @@ class SysTrayIcon(object):
|
||||||
self._on_quit = on_quit
|
self._on_quit = on_quit
|
||||||
|
|
||||||
menu_options = menu_options or ()
|
menu_options = menu_options or ()
|
||||||
menu_options = menu_options + (('Quit', None, SysTrayIcon.QUIT),)
|
menu_options = menu_options + (('Quit', None, SysTrayIcon.QUIT, None),)
|
||||||
self._next_action_id = SysTrayIcon.FIRST_ID
|
self._next_action_id = SysTrayIcon.FIRST_ID
|
||||||
self._menu_actions_by_id = set()
|
self._menu_actions_by_id = set()
|
||||||
self._menu_options = self._add_ids_to_menu_options(list(menu_options))
|
self._menu_options = self._add_ids_to_menu_options(list(menu_options))
|
||||||
|
@ -134,13 +134,20 @@ class SysTrayIcon(object):
|
||||||
def _add_ids_to_menu_options(self, menu_options):
|
def _add_ids_to_menu_options(self, menu_options):
|
||||||
result = []
|
result = []
|
||||||
for menu_option in menu_options:
|
for menu_option in menu_options:
|
||||||
option_text, option_icon, option_action = menu_option
|
option_text, option_icon, option_action, option_state = menu_option
|
||||||
if callable(option_action) or option_action in SysTrayIcon.SPECIAL_ACTIONS:
|
if callable(option_action) or option_action in SysTrayIcon.SPECIAL_ACTIONS:
|
||||||
self._menu_actions_by_id.add((self._next_action_id, option_action))
|
self._menu_actions_by_id.add((self._next_action_id, option_action))
|
||||||
result.append(menu_option + (self._next_action_id,))
|
result.append(menu_option + (self._next_action_id,))
|
||||||
|
elif option_action == 'separator':
|
||||||
|
result.append((option_text,
|
||||||
|
option_icon,
|
||||||
|
option_action,
|
||||||
|
option_state,
|
||||||
|
self._next_action_id))
|
||||||
elif non_string_iterable(option_action):
|
elif non_string_iterable(option_action):
|
||||||
result.append((option_text,
|
result.append((option_text,
|
||||||
option_icon,
|
option_icon,
|
||||||
|
option_state,
|
||||||
self._add_ids_to_menu_options(option_action),
|
self._add_ids_to_menu_options(option_action),
|
||||||
self._next_action_id))
|
self._next_action_id))
|
||||||
else:
|
else:
|
||||||
|
@ -232,22 +239,36 @@ class SysTrayIcon(object):
|
||||||
PostMessage(self._hwnd, WM_NULL, 0, 0)
|
PostMessage(self._hwnd, WM_NULL, 0, 0)
|
||||||
|
|
||||||
def _create_menu(self, menu, menu_options):
|
def _create_menu(self, menu, menu_options):
|
||||||
for option_text, option_icon, option_action, option_id in menu_options[::-1]:
|
for option_text, option_icon, option_action, option_state, option_id in menu_options[::-1]:
|
||||||
if option_icon:
|
if option_icon:
|
||||||
option_icon = self._prep_menu_icon(option_icon)
|
option_icon = self._prep_menu_icon(option_icon)
|
||||||
|
|
||||||
if option_id in self._menu_actions_by_id:
|
mi_fstate = 0
|
||||||
item = PackMENUITEMINFO(text=option_text,
|
mi_ftype = 0
|
||||||
hbmpItem=option_icon,
|
|
||||||
wID=option_id)
|
if option_state == 'default':
|
||||||
InsertMenuItem(menu, 0, 1, ctypes.byref(item))
|
mi_fstate = mi_fstate | MFS_DEFAULT
|
||||||
else:
|
if option_state == 'highlight':
|
||||||
|
mi_fstate = mi_fstate | MFS_HILITE
|
||||||
|
if option_state == 'disabled':
|
||||||
|
mi_fstate = mi_fstate | MFS_DISABLED
|
||||||
|
if option_action == 'separator':
|
||||||
|
mi_ftype = mi_ftype | MFT_SEPARATOR
|
||||||
|
|
||||||
|
if isinstance(option_action, tuple):
|
||||||
submenu = CreatePopupMenu()
|
submenu = CreatePopupMenu()
|
||||||
self._create_menu(submenu, option_action)
|
self._create_menu(submenu, option_action)
|
||||||
item = PackMENUITEMINFO(text=option_text,
|
item = PackMENUITEMINFO(text=option_text,
|
||||||
hbmpItem=option_icon,
|
hbmpItem=option_icon,
|
||||||
hSubMenu=submenu)
|
hSubMenu=submenu)
|
||||||
InsertMenuItem(menu, 0, 1, ctypes.byref(item))
|
InsertMenuItem(menu, 0, 1, ctypes.byref(item))
|
||||||
|
else:
|
||||||
|
item = PackMENUITEMINFO(text=option_text,
|
||||||
|
hbmpItem=option_icon,
|
||||||
|
wID=option_id,
|
||||||
|
fState=mi_fstate,
|
||||||
|
fType=mi_ftype)
|
||||||
|
InsertMenuItem(menu, 0, 1, ctypes.byref(item))
|
||||||
|
|
||||||
def _prep_menu_icon(self, icon):
|
def _prep_menu_icon(self, icon):
|
||||||
icon = encode_for_locale(icon)
|
icon = encode_for_locale(icon)
|
||||||
|
|
|
@ -42,10 +42,12 @@ NIM_DELETE = 2
|
||||||
NIF_ICON = 2
|
NIF_ICON = 2
|
||||||
NIF_MESSAGE = 1
|
NIF_MESSAGE = 1
|
||||||
NIF_TIP = 4
|
NIF_TIP = 4
|
||||||
|
MIIM_STATE = 1
|
||||||
MIIM_ID = 2
|
MIIM_ID = 2
|
||||||
MIIM_SUBMENU = 4
|
MIIM_SUBMENU = 4
|
||||||
MIIM_STRING = 64
|
MIIM_STRING = 64
|
||||||
MIIM_BITMAP = 128
|
MIIM_BITMAP = 128
|
||||||
|
MIIM_FTYPE = 256
|
||||||
WM_DESTROY = 2
|
WM_DESTROY = 2
|
||||||
WM_CLOSE = 16
|
WM_CLOSE = 16
|
||||||
WM_COMMAND = 273
|
WM_COMMAND = 273
|
||||||
|
@ -70,6 +72,10 @@ SM_CXSMICON = 49
|
||||||
SM_CYSMICON = 50
|
SM_CYSMICON = 50
|
||||||
COLOR_MENU = 4
|
COLOR_MENU = 4
|
||||||
DI_NORMAL = 3
|
DI_NORMAL = 3
|
||||||
|
MFS_DISABLED = 3
|
||||||
|
MFS_DEFAULT = 4096
|
||||||
|
MFS_HILITE = 128
|
||||||
|
MFT_SEPARATOR = 2048
|
||||||
|
|
||||||
WPARAM = ctypes.wintypes.WPARAM
|
WPARAM = ctypes.wintypes.WPARAM
|
||||||
LPARAM = ctypes.wintypes.LPARAM
|
LPARAM = ctypes.wintypes.LPARAM
|
||||||
|
@ -145,7 +151,8 @@ class NOTIFYICONDATA(ctypes.Structure):
|
||||||
_fields_.append(("hBalloonIcon", HANDLE))
|
_fields_.append(("hBalloonIcon", HANDLE))
|
||||||
|
|
||||||
|
|
||||||
def PackMENUITEMINFO(text=None, hbmpItem=None, wID=None, hSubMenu=None):
|
def PackMENUITEMINFO(text=None, hbmpItem=None, wID=None, hSubMenu=None,
|
||||||
|
fType=None, fState=None):
|
||||||
res = MENUITEMINFO()
|
res = MENUITEMINFO()
|
||||||
res.cbSize = ctypes.sizeof(res)
|
res.cbSize = ctypes.sizeof(res)
|
||||||
res.fMask = 0
|
res.fMask = 0
|
||||||
|
@ -162,6 +169,12 @@ def PackMENUITEMINFO(text=None, hbmpItem=None, wID=None, hSubMenu=None):
|
||||||
if hSubMenu is not None:
|
if hSubMenu is not None:
|
||||||
res.fMask |= MIIM_SUBMENU
|
res.fMask |= MIIM_SUBMENU
|
||||||
res.hSubMenu = hSubMenu
|
res.hSubMenu = hSubMenu
|
||||||
|
if fType is not None:
|
||||||
|
res.fMask |= MIIM_FTYPE
|
||||||
|
res.fType = fType
|
||||||
|
if fState is not None:
|
||||||
|
res.fMask |= MIIM_STATE
|
||||||
|
res.fState = fState
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def LOWORD(w):
|
def LOWORD(w):
|
||||||
|
|
|
@ -386,7 +386,17 @@ def win_system_tray():
|
||||||
from systray import SysTrayIcon
|
from systray import SysTrayIcon
|
||||||
|
|
||||||
def tray_open(sysTrayIcon):
|
def tray_open(sysTrayIcon):
|
||||||
launch_browser(CONFIG.HTTP_HOST, HTTP_PORT, HTTP_ROOT)
|
launch_browser(plexpy.CONFIG.HTTP_HOST, plexpy.HTTP_PORT, plexpy.HTTP_ROOT)
|
||||||
|
|
||||||
|
def tray_check_update(sysTrayIcon):
|
||||||
|
versioncheck.check_update()
|
||||||
|
|
||||||
|
def tray_update(sysTrayIcon):
|
||||||
|
if plexpy.UPDATE_AVAILABLE:
|
||||||
|
plexpy.SIGNAL = 'update'
|
||||||
|
else:
|
||||||
|
hover_text = common.PRODUCT + ' - No Update Available'
|
||||||
|
plexpy.WIN_SYS_TRAY_ICON.update(hover_text=hover_text)
|
||||||
|
|
||||||
def tray_restart(sysTrayIcon):
|
def tray_restart(sysTrayIcon):
|
||||||
plexpy.SIGNAL = 'restart'
|
plexpy.SIGNAL = 'restart'
|
||||||
|
@ -394,10 +404,18 @@ def win_system_tray():
|
||||||
def tray_quit(sysTrayIcon):
|
def tray_quit(sysTrayIcon):
|
||||||
plexpy.SIGNAL = 'shutdown'
|
plexpy.SIGNAL = 'shutdown'
|
||||||
|
|
||||||
icon = os.path.join(PROG_DIR, 'data/interfaces/', CONFIG.INTERFACE, 'images/logo.ico')
|
if plexpy.UPDATE_AVAILABLE:
|
||||||
hover_text = common.PRODUCT
|
icon = os.path.join(plexpy.PROG_DIR, 'data/interfaces/', plexpy.CONFIG.INTERFACE, 'images/logo_tray-update.ico')
|
||||||
menu_options = (('Open Tautulli', None, tray_open),
|
hover_text = common.PRODUCT + ' - Update Available!'
|
||||||
('Restart', None, tray_restart))
|
else:
|
||||||
|
icon = os.path.join(plexpy.PROG_DIR, 'data/interfaces/', plexpy.CONFIG.INTERFACE, 'images/logo_tray.ico')
|
||||||
|
hover_text = common.PRODUCT
|
||||||
|
|
||||||
|
menu_options = (('Open Tautulli', None, tray_open, 'default'),
|
||||||
|
('', None, 'separator', None),
|
||||||
|
('Check for Updates', None, tray_check_update, None),
|
||||||
|
('Update', None, tray_update, None),
|
||||||
|
('Restart', None, tray_restart, None))
|
||||||
|
|
||||||
logger.info(u"Launching system tray icon.")
|
logger.info(u"Launching system tray icon.")
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,15 @@ def check_update(auto_update=False, notify=False):
|
||||||
else:
|
else:
|
||||||
plexpy.UPDATE_AVAILABLE = False
|
plexpy.UPDATE_AVAILABLE = False
|
||||||
|
|
||||||
|
if plexpy.WIN_SYS_TRAY_ICON:
|
||||||
|
if plexpy.UPDATE_AVAILABLE:
|
||||||
|
icon = os.path.join(plexpy.PROG_DIR, 'data/interfaces/', plexpy.CONFIG.INTERFACE, 'images/logo-update.ico')
|
||||||
|
hover_text = common.PRODUCT + ' - Update Available!'
|
||||||
|
else:
|
||||||
|
icon = os.path.join(plexpy.PROG_DIR, 'data/interfaces/', plexpy.CONFIG.INTERFACE, 'images/logo.ico')
|
||||||
|
hover_text = common.PRODUCT + ' - No Update Available'
|
||||||
|
plexpy.WIN_SYS_TRAY_ICON.update(icon=icon, hover_text=hover_text)
|
||||||
|
|
||||||
|
|
||||||
def check_github(auto_update=False, notify=False):
|
def check_github(auto_update=False, notify=False):
|
||||||
plexpy.COMMITS_BEHIND = 0
|
plexpy.COMMITS_BEHIND = 0
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue