Added taskbar
This commit is contained in:
parent
79ed46f889
commit
1f43632928
@ -1,6 +1,9 @@
|
||||
# Pytop
|
||||
Pytop is a Gtk + Python gui to have a custom desktop interface.
|
||||
|
||||
# Updates
|
||||
Added task bar.
|
||||
|
||||
# Notes
|
||||
```sudo apt-get install python3 wget steamcmd```
|
||||
|
||||
|
Binary file not shown.
@ -15,12 +15,12 @@ from setproctitle import setproctitle
|
||||
|
||||
# Application imports
|
||||
from utils import Settings
|
||||
from signal_classes import CrossClassSignals, GridSignals
|
||||
from signal_classes import CrossClassSignals, GridSignals, TaskbarSignals
|
||||
|
||||
|
||||
class Main:
|
||||
setproctitle('Pytop')
|
||||
def __init__(self):
|
||||
setproctitle('Pytop')
|
||||
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, gtk.main_quit)
|
||||
faulthandler.enable() # For better debug info
|
||||
|
||||
@ -31,7 +31,8 @@ class Main:
|
||||
# Gets the methods from the classes and sets to handler.
|
||||
# Then, builder connects to any signals it needs.
|
||||
classes = [CrossClassSignals(settings),
|
||||
GridSignals(settings)]
|
||||
GridSignals(settings),
|
||||
TaskbarSignals(settings)]
|
||||
|
||||
handlers = {}
|
||||
for c in classes:
|
||||
|
@ -67,7 +67,7 @@
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin">6</property>
|
||||
<property name="selection_mode">multiple</property>
|
||||
<property name="columns">6</property>
|
||||
<property name="item_width">72</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@ -79,6 +79,62 @@
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="height_request">64</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="vscrollbar_policy">never</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkButtonBox" id="taskBarButtons">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">start</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButtonBox" id="taskBarWorkspaces">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">start</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@ -87,6 +143,134 @@
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-new</property>
|
||||
</object>
|
||||
<object class="GtkPopover" id="taskbarMenu">
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkButtonBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="layout_style">start</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Minimize</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="toggleMinimize" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Maximize</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="toggleMaximize" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Move</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="startMoveWindow" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label" translatable="yes">Resixze</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<signal name="clicked" handler="startResizeWindow" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton">
|
||||
<property name="label" translatable="yes">Always On Top</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="setTopState" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton">
|
||||
<property name="label" translatable="yes">Always Below</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="setBelowState" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton">
|
||||
<property name="label" translatable="yes">Always On Visible Workspace</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="setWorkspacePin" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="closeAppWindow" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">7</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkImage" id="trashImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
|
181
src/Pytop/signal_classes/TaskbarSignals.py
Normal file
181
src/Pytop/signal_classes/TaskbarSignals.py
Normal file
@ -0,0 +1,181 @@
|
||||
# Gtk imports
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
gi.require_version('Gdk', '3.0')
|
||||
gi.require_version('Wnck', '3.0')
|
||||
|
||||
from gi.repository import Wnck as wnck
|
||||
from gi.repository import Gtk as gtk
|
||||
from gi.repository import Gdk as gdk
|
||||
from gi.repository import GLib
|
||||
|
||||
|
||||
# Python imports
|
||||
import threading
|
||||
|
||||
# Application imports
|
||||
|
||||
|
||||
|
||||
def threaded(fn):
|
||||
def wrapper(*args, **kwargs):
|
||||
threading.Thread(target=fn, args=args, kwargs=kwargs).start()
|
||||
|
||||
return wrapper
|
||||
|
||||
class MouseButtons:
|
||||
LEFT_BUTTON = 1
|
||||
RIGHT_BUTTON = 3
|
||||
|
||||
|
||||
class TaskbarSignals:
|
||||
def __init__(self, settings):
|
||||
self.settings = settings
|
||||
self.builder = self.settings.returnBuilder()
|
||||
self.taskBarButtons = self.builder.get_object('taskBarButtons')
|
||||
self.taskbarMenu = self.builder.get_object('taskbarMenu')
|
||||
|
||||
self.SCREEN = wnck.Screen.get_default()
|
||||
self.actv_workspace_num = None
|
||||
self.window = None
|
||||
|
||||
self.SCREEN.force_update() # (Re)populate screen windows list
|
||||
self.refreashTaskbar()
|
||||
self.setScreenSignals()
|
||||
self.setPagerWidget()
|
||||
|
||||
|
||||
def refreashTaskbar(self):
|
||||
workspace = self.SCREEN.get_active_workspace()
|
||||
self.actv_workspace_num = workspace.get_number()
|
||||
|
||||
windows = self.SCREEN.get_windows()
|
||||
for w in windows:
|
||||
if workspace and w.get_workspace():
|
||||
wnum = w.get_workspace().get_number()
|
||||
if not w.is_skip_pager() and not w.is_skip_tasklist() and wnum == self.actv_workspace_num:
|
||||
btn = self.createWinBttn(w)
|
||||
self.setupSignals(btn, w)
|
||||
self.taskBarButtons.add(btn)
|
||||
|
||||
def setupSignals(self, btn, win):
|
||||
btn.connect("button-press-event", self.clickEvent, (win))
|
||||
|
||||
def setScreenSignals(self):
|
||||
self.SCREEN.connect("active-workspace-changed", self.activeWorkspaceChanged)
|
||||
# self.SCREEN.connect("application-opened", self.applicationOpened)
|
||||
# self.SCREEN.connect("application-closed", self.applicationClosed)
|
||||
self.SCREEN.connect("window-opened", self.windowOpened)
|
||||
self.SCREEN.connect("window-closed", self.windowClosed)
|
||||
|
||||
def createWinBttn(self, w):
|
||||
btn = gtk.Button(label=w.get_name(), always_show_image=True)
|
||||
img = gtk.Image()
|
||||
img.set_from_pixbuf( w.get_icon() ) # w.get_mini_icon() or w.get_icon()
|
||||
btn.set_image(img)
|
||||
btn.show()
|
||||
return btn
|
||||
|
||||
def clickEvent(self, widget, e, window):
|
||||
if e.type == gdk.EventType.BUTTON_PRESS and e.button == MouseButtons.LEFT_BUTTON:
|
||||
if not window.is_minimized():
|
||||
window.minimize()
|
||||
else:
|
||||
window.activate(1)
|
||||
if e.type == gdk.EventType.BUTTON_PRESS and e.button == MouseButtons.RIGHT_BUTTON:
|
||||
self.window = window
|
||||
self.taskbarMenu.set_relative_to(widget)
|
||||
self.taskbarMenu.popup()
|
||||
|
||||
def setPagerWidget(self):
|
||||
pager = wnck.Pager()
|
||||
self.builder.get_object('taskBarWorkspaces').add(pager)
|
||||
|
||||
# ---- Screen Events ----
|
||||
# NOTE: This is the worst way of doing this and kids die when these are run.
|
||||
# We need to filter actions and more like add/remove buttons than just
|
||||
# clearing everything. I'm sorry to all the families hurt by this....
|
||||
def activeWorkspaceChanged(self, screen, workspace):
|
||||
self.clearChildren(self.taskBarButtons)
|
||||
self.SCREEN = screen
|
||||
self.SCREEN.force_update() # (Re)populate screen windows list
|
||||
self.refreashTaskbar()
|
||||
def windowOpened(self, screen, window):
|
||||
self.SCREEN.force_update() # (Re)populate screen windows list
|
||||
btn = self.createWinBttn(window)
|
||||
self.setupSignals(btn, window)
|
||||
self.taskBarButtons.add(btn)
|
||||
def windowClosed(self, screen, window):
|
||||
self.clearChildren(self.taskBarButtons)
|
||||
self.SCREEN.force_update() # (Re)populate screen windows list
|
||||
self.refreashTaskbar()
|
||||
|
||||
def clearChildren(self, parent):
|
||||
children = parent.get_children();
|
||||
for child in parent:
|
||||
child.destroy()
|
||||
|
||||
# ---- Taskbar Button Events ----
|
||||
def toggleMinimize(self, widget, data=None):
|
||||
if not self.window.is_minimized():
|
||||
self.window.minimize()
|
||||
widget.set_label("Unminimize")
|
||||
else:
|
||||
self.window.activate(1)
|
||||
widget.set_label("Minimize")
|
||||
|
||||
def toggleMaximize(self, widget, data=None):
|
||||
if not self.window.is_maximized():
|
||||
self.window.maximize()
|
||||
widget.set_label("Unmaximize")
|
||||
else:
|
||||
self.window.unmaximize()
|
||||
widget.set_label("Maximize")
|
||||
|
||||
def startMoveWindow(self, widget, data=None):
|
||||
self.window.keyboard_move()
|
||||
|
||||
def startResizeWindow(self, widget, data=None):
|
||||
self.window.keyboard_size()
|
||||
|
||||
def setTopState(self, widget):
|
||||
if not self.window.is_above():
|
||||
self.window.make_above()
|
||||
else:
|
||||
self.window.unmake_above()
|
||||
|
||||
def setBelowState(self, widget):
|
||||
if not self.window.is_above():
|
||||
self.window.make_below()
|
||||
else:
|
||||
self.window.unmake_below()
|
||||
|
||||
def setWorkspacePin(self, widget):
|
||||
if not self.window.is_pinned():
|
||||
self.window.pin()
|
||||
else:
|
||||
self.window.unpin()
|
||||
|
||||
def closeAppWindow(self, widget, data=None):
|
||||
self.window.close(1)
|
||||
|
||||
|
||||
# WINDOW_SIGNALS
|
||||
# print(w.get_icon())
|
||||
# w.get_name()
|
||||
# w.get_icon()
|
||||
# w.get_mini_icon()
|
||||
# w.make_above()
|
||||
# w. pin()
|
||||
# w. get_state() # https://lazka.github.io/pgi-docs/Wnck-3.0/flags.html#Wnck.WindowState
|
||||
# w.get_workspace()
|
||||
# w.set_workspace(workspace)
|
||||
# w.close()
|
||||
# w.is_above()
|
||||
# w.is_active()
|
||||
# w.is_below()
|
||||
# w.is_fullscreen()
|
||||
# w.is_maximized()
|
||||
# w.is_minimized()
|
||||
# w.is_pinned()
|
||||
# w.is_sticky()
|
@ -1,2 +1,3 @@
|
||||
from signal_classes.CrossClassSignals import CrossClassSignals
|
||||
from signal_classes.GridSignals import GridSignals
|
||||
from signal_classes.TaskbarSignals import TaskbarSignals
|
||||
|
@ -35,24 +35,22 @@ class FileHandler:
|
||||
self.TRASHINFOFOLDER = settings.returnTrshInfoPth()
|
||||
|
||||
|
||||
|
||||
@threaded
|
||||
def openFile(self, file):
|
||||
print("Opening: " + file)
|
||||
if file.lower().endswith(self.vids):
|
||||
subprocess.Popen([self.MEDIAPLAYER, self.MPV_WH, file])
|
||||
subprocess.Popen([self.MEDIAPLAYER, self.MPV_WH, file], stdout=subprocess.PIPE)
|
||||
elif file.lower().endswith(self.music):
|
||||
subprocess.Popen([self.MUSICPLAYER, file])
|
||||
subprocess.Popen([self.MUSICPLAYER, file], stdout=subprocess.PIPE)
|
||||
elif file.lower().endswith(self.images):
|
||||
subprocess.Popen([self.IMGVIEWER, file])
|
||||
subprocess.Popen([self.IMGVIEWER, file], stdout=subprocess.PIPE)
|
||||
elif file.lower().endswith(self.txt):
|
||||
subprocess.Popen([self.TEXTVIEWER, file])
|
||||
subprocess.Popen([self.TEXTVIEWER, file], stdout=subprocess.PIPE)
|
||||
elif file.lower().endswith(self.pdf):
|
||||
subprocess.Popen([self.PDFVIEWER, file])
|
||||
subprocess.Popen([self.PDFVIEWER, file], stdout=subprocess.PIPE)
|
||||
elif file.lower().endswith(self.office):
|
||||
subprocess.Popen([self.OFFICEPROG, file])
|
||||
subprocess.Popen([self.OFFICEPROG, file], stdout=subprocess.PIPE)
|
||||
else:
|
||||
subprocess.Popen(['xdg-open', file])
|
||||
subprocess.Popen(['xdg-open', file], stdout=subprocess.PIPE)
|
||||
|
||||
|
||||
def create(self, name, type):
|
||||
|
@ -50,7 +50,7 @@ class Grid:
|
||||
self.grid.connect("item-activated", self.iconDblLeftClick)
|
||||
self.grid.connect("button_release_event", self.iconSingleClick, (self.grid,))
|
||||
|
||||
|
||||
# @threaded
|
||||
def setNewDirectory(self, path):
|
||||
self.currentPath = path
|
||||
dirPaths = ['.', '..']
|
||||
@ -112,7 +112,8 @@ class Grid:
|
||||
for dataSet in self.toWorkPool:
|
||||
self.store.append([dataSet[0].get_pixbuf(), dataSet[1]])
|
||||
|
||||
self.toWorkPool.clear()
|
||||
self.toWorkPool.clear()
|
||||
|
||||
if len(self.store) == len(files): # Processed all files
|
||||
return False
|
||||
else: # Check again when idle
|
||||
|
Loading…
Reference in New Issue
Block a user