aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2015-04-04 15:38:23 +0200
committerMattias Andrée <maandree@operamail.com>2015-04-04 15:38:23 +0200
commit11f3c6944d77b21c4858dc29d5fe2cae84be6a46 (patch)
tree5c22052a84768fecb743afeefad8fe6ac51d18d7 /src/plugins
parent.desktop file support (diff)
downloadxpybar-11f3c6944d77b21c4858dc29d5fe2cae84be6a46.tar.gz
xpybar-11f3c6944d77b21c4858dc29d5fe2cae84be6a46.tar.bz2
xpybar-11f3c6944d77b21c4858dc29d5fe2cae84be6a46.tar.xz
beginning on menu plugin
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/menu.py151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/plugins/menu.py b/src/plugins/menu.py
new file mode 100644
index 0000000..2f9d43b
--- /dev/null
+++ b/src/plugins/menu.py
@@ -0,0 +1,151 @@
+# -*- python -*-
+'''
+xpybar – xmobar replacement written in python
+Copyright © 2014, 2015 Mattias Andrée (maandree@member.fsf.org)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+'''
+
+
+class Menu:
+ '''
+ Dropdown menu
+
+ Instances of this class is compatible with `Bar`
+
+ You should extend the global function `stop` to unmap any menu that
+ is still open at the time that function is called
+
+ @variable window The X window
+ @variable gc The window's graphics context
+ @variable cmap The window's colour map
+ @variable width:int The menu's pixel width
+ @variable height:int The output's pixel height
+ @variable left:int The output's left position
+ @variable top:int The output's top position
+ @variable ypos:int The position of the menu in relation to either the top or bottom edge of the output
+ @variable panel_height:int The menu's height, note that the name is `panel_height` for compatibility with `Bar`
+ @variable at_top:bool Whether the menu is to be positioned relative the top of the output, otherwise to the bottom
+ @variable background The default background
+ @variable foreground The default foreground
+ @variable font The default font
+ @variable font_metrics The default font's metrics
+ @variable font_height:int The height of the default font
+ @variable font_width:int The width of an 'X' with the default font
+ @variable palette A 16-array of standard colours
+ @variable cmap_cache Custom colour map cache
+ '''
+
+
+ methods_set = False
+ '''
+ :bool Indicates whether a constructor has set methods common with `Bar`
+ '''
+
+
+ def __init__(self, output, width, height, xpos, ypos, left, top, font = None,
+ background = None, foreground = None, event_mask = None, override_redirect = True):
+ '''
+ Constructor
+
+ @param output:int The index of the output within the screen as printed by xrandr, except primary is first
+ @param width:int The width of the menu
+ @param height:int The height of the menu
+ @param xpos:int The position of the menu in relation the either the left or right edge of the output
+ @param ypos:int The position of the menu in relation the either the top or bottom edge of the output
+ @param left:int Whether the menu is positioned relative to the left of the output, otherwise to the right
+ @param top:int Whether the menu is positioned relative to the top of the output, otherwise to the bottom
+ @param font:str? The default font, `None` for the default
+ @param background:(red:int, green:int, blue:int)? The default background, `None` for the default
+ @param foreground:(red:int, green:int, blue:int)? The default foreground, `None` for the default
+ @param event:int? Mask of events that should be caught, `None` for the default
+ @param override_redirect:bool Whether override_redirect should be set
+ '''
+ import os
+ import Xlib.display, Xlib.Xatom, Xlib.ext.randr, Xlib.X
+
+ if not Menu.methods_set:
+ Menu.map = Bar.map
+ Menu.unmap = Bar.unmap
+ Menu.text_width = Bar.text_width
+ Menu.draw_text = Bar.draw_text
+ Menu.draw_coloured_text = Bar.draw_coloured_text
+ Menu.draw_coloured_splitted_text = Bar.draw_coloured_splitted_text
+ Menu.create_colour = Bar.create_colour
+ Menu.create_font = Bar.create_font
+ Menu.change_colour = Bar.change_colour
+ Menu.change_font = Bar.change_font
+ Menu.clear_rectangle = Bar.clear_rectangle
+ Menu.clear = Bar.clear
+ Menu.invalidate = Bar.invalidate
+ Menu.coloured_length = Bar.coloured_length
+ Menu.methods_set = True
+
+ if event_mask is None:
+ event_mask = ( Xlib.X.StructureNotifyMask
+ | Xlib.X.ButtonPressMask
+ | Xlib.X.ButtonReleaseMask
+ | Xlib.X.ExposureMask
+ | Xlib.X.KeyPress
+ | Xlib.X.KeyRelease
+ | Xlib.X.MotionNotify
+ | Xlib.X.EnterNotify
+ | Xlib.X.LeaveNotify
+ )
+ if font is None: font = FONT
+ if background is None: background = BACKGROUND
+ if foreground is None: foreground = FOREGROUND
+
+ [self.width, self.height, self.left, self.top] = outputs[output][:4]
+ [self.ypos, self.panel_height, self.at_top] = [ypos, height, top]
+ self.left += xpos if left else (self.width - xpos - width)
+ self.top += ypos if top else (self.height - ypos - height)
+ self.width = width
+
+ self.window = screen.root.create_window(self.left, self.top, self.width, self.panel_height, 0,
+ Xlib.X.CopyFromParent,
+ Xlib.X.InputOutput,
+ Xlib.X.CopyFromParent,
+ event_mask = event_mask,
+ colormap = Xlib.X.CopyFromParent,
+ override_redirect = override_redirect)
+
+ self.window.set_wm_name('xpybar')
+ self.window.set_wm_icon_name('xpybar')
+ self.window.set_wm_class('menu', 'xpybar')
+ self.window.set_wm_client_machine(os.uname().nodename)
+
+ _CARD = display.intern_atom("CARDINAL")
+ _DESKTOP = display.intern_atom("_NET_WM_DESKTOP")
+ _PID = display.intern_atom("_NET_WM_PID")
+ self.window.change_property(_DESKTOP, _CARD, 32, [0xFFFFFFFF])
+ self.window.change_property(_PID, _CARD, 32, [os.getpid()])
+
+ _ATOM = display.intern_atom("ATOM")
+ _TYPE = display.intern_atom("_NET_WM_WINDOW_TYPE")
+ _NORMAL = display.intern_atom("_NET_WM_WINDOW_TYPE_NORMAL")
+ self.window.change_property(_TYPE, _ATOM, 32, [_NORMAL])
+
+ self.gc = self.window.create_gc()
+ self.cmap = self.window.get_attributes().colormap
+ self.cmap_cache = {}
+ self.background = self.create_colour(*background)
+ self.foreground = self.create_colour(*foreground)
+ (self.font, self.font_metrics, self.font_height) = self.create_font(font)
+ self.font_width = self.text_width('X')
+ self.palette = [0x000000, 0xCD656C, 0x32A679, 0xCCAD47, 0x2495BE, 0xA46EB0, 0x00A09F, 0xD8D8D8]
+ self.palette += [0x555555, 0xEB5E6A, 0x0EC287, 0xF2CA38, 0x00ACE0, 0xC473D1, 0x00C3C7, 0xEEEEEE]
+ self.palette = [((p >> 16) & 255, (p >> 8) & 255, p & 255) for p in self.palette]
+ self.palette = [self.create_colour(*p) for p in self.palette]
+