示例#1
0
    def run(self):
        # Establish socket connection
        conn = Connection()

        # Get window tree and name of focused window
        tree = conn.get_tree()
        win_name = tree.find_focused().name

        self.output = {"full_text": win_name, "color": self.color, "urgent": False}
示例#2
0
#!/usr/bin/env python3

from i3ipc import Connection

i3 = Connection()
tree = i3.get_tree()

for conn in tree:
    if conn.name and "youtube" in conn.name.lower():
        conn.command("move scratchpad")
示例#3
0
#!/usr/bin/env python3

from i3ipc import Connection
from subprocess import call

i3 = Connection()


def windownotify(i3, event):
    if event.container.fullscreen_mode == 0:
        call('polybar-msg cmd show'.split(' '))
    else:
        call('polybar-msg cmd hide'.split(' '))

        #print(event.container.fullscreen_mode)


i3.on('window', windownotify)

i3.main()
示例#4
0
#!/usr/bin/env python3
from i3ipc import Connection, Event
from subprocess import call
import os
i3 = Connection()
th = 'polybar-msg hook titlehook 1'
show = 'polybar-msg cmd show'
hide = 'polybar-msg cmd hide'
bh = 'polybar-msg hook backupd 1'
ws = 'polybar-msg hook wshook 1'
ws1 = 'polybar-msg hook wshook1 1'


def windownotify(i3, event):
    # if event.container.fullscreen_mode == 0:
    #     os.system(show)
    #     #call('polybar-msg cmd show'.split(' '))
    # else:
    #     os.system(hide)
    #     #call('polybar-msg cmd hide'.split(' '))

    if event.change in "focus" "title":
        os.system(th)
        #call('polybar-msg hook titlehook 1'.split(' '))

    if event.change in "focus" "title":
        os.system(bh)
        #call('polybar-msg hook backupd 1'.split(' '))


def wsnotify(i3, event):
示例#5
0
def get_ws():
    i3 = Connection()
    ws = i3.get_tree().find_focused().workspace().name
    return int(ws[0])
示例#6
0
#!/usr/bin/python
import argparse
import sys

# too slow?

from i3ipc import Connection

parser = argparse.ArgumentParser()
parser.add_argument('--name',
                    type=str,
                    help='name of the scratchpad',
                    required=True)
args = parser.parse_args()

i3 = Connection()

programs = ['TelegramDesktop', 'Skype']

prog_name = vars(args)['name']

scratchpad_windows = [
    leaf.window_class for leaf in i3.get_tree().scratchpad().leaves()
]

if __name__ == '__main__':
    if prog_name not in programs:
        print('unknown program name')
        sys.exit(0)

    if prog_name in scratchpad_windows:
示例#7
0
#!/usr/bin/env python3
from i3ipc import Connection, Event
import i3ipc.events as events
import time, os, subprocess

sway = Connection()


def show_notification(text, timeout=1000):
    proc = subprocess.Popen(['notify-send', text, '-t', str(timeout)])
    proc.wait(2)


def on_ws_init(_, e: events.WorkspaceEvent):
    print('ws init', e.current.name)

    # Start VS Code on workspace 2
    if e.current.name == '2' and os.system('pgrep code') != 0:
        show_notification('Launching VS Code...', 2000)
        sway.command('exec code')

    # Start Firefox on workspace 3
    if e.current.name == '3' and os.system('pgrep firefox') != 0:
        show_notification('Launching Firefox...', 3000)
        sway.command('exec firefox')


sway.on(Event.WORKSPACE_INIT, on_ws_init)

sway.get_workspaces()
示例#8
0
#!/usr/bin/env python3
from i3ipc import Connection, ModeEvent


def write_to_file(message):
    with open("/tmp/binding_mode", "w") as file:
        file.write(message)


def on_event_change(i3, data):
    if data.change == 'default':
        message = " "
    else:
        message = data.change
    write_to_file(message)


write_to_file(' ')
i3 = Connection()
i3.on('mode', on_event_change)
i3.main()
示例#9
0
#!/usr/bin/env python3

from i3ipc import Connection
from subprocess import call
from re import sub

i3 = Connection()


def thunar(event):

    print('window is thunar')

    ins = format(event.container.window_instance)
    wid = format(event.container.window)
    # cid = format(event.container.id)
    ttl = format(event.container.name)
    newttl = sub(" - File Manager$", "", ttl)

    event.container.command("title_format %s" % (newttl))

    cmd = ["updatefm", "-p", newttl, "-i", ins, "-d", wid]

    call(cmd)


def windownotify(i3, event):

    print('window notify method')

    if event.container.window_class == 'ThunarD':
示例#10
0
    def __init__(self,
                 *,
                 private: bool,
                 geometry: Optional[QByteArray] = None,
                 parent: Optional[QWidget] = None) -> None:
        """Create a new main window.

        Args:
            geometry: The geometry to load, as a bytes-object (or None).
            private: Whether the window is in private browsing mode.
            parent: The parent the window should get.
        """
        super().__init__(parent)
        self.setAttribute(Qt.WA_TranslucentBackground)
        # Late import to avoid a circular dependency
        # - browsertab -> hints -> webelem -> mainwindow -> bar -> browsertab
        from qutebrowser.mainwindow import tabbedbrowser
        from qutebrowser.mainwindow.statusbar import bar

        self.setAttribute(Qt.WA_DeleteOnClose)
        if config.val.window.transparent:
            self.setAttribute(Qt.WA_TranslucentBackground)
            self.palette().setColor(QPalette.Window, Qt.transparent)

        self._overlays: MutableSequence[_OverlayInfoType] = []
        self.win_id = next(win_id_gen)
        self.registry = objreg.ObjectRegistry()
        objreg.window_registry[self.win_id] = self
        objreg.register('main-window',
                        self,
                        scope='window',
                        window=self.win_id)
        tab_registry = objreg.ObjectRegistry()
        objreg.register('tab-registry',
                        tab_registry,
                        scope='window',
                        window=self.win_id)

        self.setWindowTitle('qutebrowser')
        self._vbox = QVBoxLayout(self)
        self._vbox.setContentsMargins(0, 0, 0, 0)
        self._vbox.setSpacing(0)

        self._init_downloadmanager()
        self._downloadview = downloadview.DownloadView(
            model=self._download_model)

        self.is_private = config.val.content.private_browsing or private

        self.tabbed_browser: tabbedbrowser.TabbedBrowser = tabbedbrowser.TabbedBrowser(
            win_id=self.win_id, private=self.is_private, parent=self)
        objreg.register('tabbed-browser',
                        self.tabbed_browser,
                        scope='window',
                        window=self.win_id)
        self._init_command_dispatcher()

        # We need to set an explicit parent for StatusBar because it does some
        # show/hide magic immediately which would mean it'd show up as a
        # window.
        self.status = bar.StatusBar(win_id=self.win_id,
                                    private=self.is_private,
                                    parent=self)

        self._add_widgets()
        self._downloadview.show()

        self._init_completion()

        log.init.debug("Initializing modes...")
        modeman.init(win_id=self.win_id, parent=self)

        self._commandrunner = runners.CommandRunner(self.win_id,
                                                    partial_match=True)

        self._keyhint = keyhintwidget.KeyHintView(self.win_id, self)
        self._add_overlay(self._keyhint, self._keyhint.update_geometry)

        self._prompt_container = prompt.PromptContainer(self.win_id, self)
        self._add_overlay(self._prompt_container,
                          self._prompt_container.update_geometry,
                          centered=True,
                          padding=10)
        objreg.register('prompt-container',
                        self._prompt_container,
                        scope='window',
                        window=self.win_id,
                        command_only=True)
        self._prompt_container.hide()

        self._messageview = messageview.MessageView(parent=self)
        self._add_overlay(self._messageview, self._messageview.update_geometry)

        self._xkb_switch = xkbswitch.XkbSwitchPlugin(win_id=self.win_id,
                                                     parent=self)

        self._init_geometry(geometry)
        self._connect_signals()

        # When we're here the statusbar might not even really exist yet, so
        # resizing will fail. Therefore, we use singleShot QTimers to make sure
        # we defer this until everything else is initialized.
        QTimer.singleShot(0, self._connect_overlay_signals)
        config.instance.changed.connect(self._on_config_changed)

        objects.qapp.new_window.emit(self)
        self._set_decoration(config.val.window.hide_decoration)

        self.state_before_fullscreen = self.windowState()
        stylesheet.set_register(self)

        global i3ipc_used
        if i3ipc_used:
            try:
                self.wm_connection = WMConnection()
                response = self.wm_connection.get_version()
                self.wm_variant = 'i3'
                if 'variant' in response.ipc_data and response.ipc_data[
                        'variant'] == 'sway':
                    self.wm_variant = 'sway'
            except:
                i3ipc_used = False
示例#11
0
class MainWindow(QWidget):
    """The main window of qutebrowser.

    Adds all needed components to a vbox, initializes sub-widgets and connects
    signals.

    Attributes:
        status: The StatusBar widget.
        tabbed_browser: The TabbedBrowser widget.
        state_before_fullscreen: window state before activation of fullscreen.
        _downloadview: The DownloadView widget.
        _download_model: The DownloadModel instance.
        _vbox: The main QVBoxLayout.
        _commandrunner: The main CommandRunner instance.
        _overlays: Widgets shown as overlay for the current webpage.
        _private: Whether the window is in private browsing mode.
    """

    # Application wide stylesheets
    STYLESHEET = """
        HintLabel {
            background-color: {{ conf.colors.hints.bg }};
            color: {{ conf.colors.hints.fg }};
            font: {{ conf.fonts.hints }};
            border: {{ conf.hints.border }};
            border-radius: {{ conf.hints.radius }}px;
            padding-top: {{ conf.hints.padding['top'] }}px;
            padding-left: {{ conf.hints.padding['left'] }}px;
            padding-right: {{ conf.hints.padding['right'] }}px;
            padding-bottom: {{ conf.hints.padding['bottom'] }}px;
        }

        QMenu {
            {% if conf.fonts.contextmenu %}
                font: {{ conf.fonts.contextmenu }};
            {% endif %}
            {% if conf.colors.contextmenu.menu.bg %}
                background-color: {{ conf.colors.contextmenu.menu.bg }};
            {% endif %}
            {% if conf.colors.contextmenu.menu.fg %}
                color: {{ conf.colors.contextmenu.menu.fg }};
            {% endif %}
        }

        QMenu::item:selected {
            {% if conf.colors.contextmenu.selected.bg %}
                background-color: {{ conf.colors.contextmenu.selected.bg }};
            {% endif %}
            {% if conf.colors.contextmenu.selected.fg %}
                color: {{ conf.colors.contextmenu.selected.fg }};
            {% endif %}
        }

        QMenu::item:disabled {
            {% if conf.colors.contextmenu.disabled.bg %}
                background-color: {{ conf.colors.contextmenu.disabled.bg }};
            {% endif %}
            {% if conf.colors.contextmenu.disabled.fg %}
                color: {{ conf.colors.contextmenu.disabled.fg }};
            {% endif %}
        }
    """

    def __init__(self,
                 *,
                 private: bool,
                 geometry: Optional[QByteArray] = None,
                 parent: Optional[QWidget] = None) -> None:
        """Create a new main window.

        Args:
            geometry: The geometry to load, as a bytes-object (or None).
            private: Whether the window is in private browsing mode.
            parent: The parent the window should get.
        """
        super().__init__(parent)
        self.setAttribute(Qt.WA_TranslucentBackground)
        # Late import to avoid a circular dependency
        # - browsertab -> hints -> webelem -> mainwindow -> bar -> browsertab
        from qutebrowser.mainwindow import tabbedbrowser
        from qutebrowser.mainwindow.statusbar import bar

        self.setAttribute(Qt.WA_DeleteOnClose)
        if config.val.window.transparent:
            self.setAttribute(Qt.WA_TranslucentBackground)
            self.palette().setColor(QPalette.Window, Qt.transparent)

        self._overlays: MutableSequence[_OverlayInfoType] = []
        self.win_id = next(win_id_gen)
        self.registry = objreg.ObjectRegistry()
        objreg.window_registry[self.win_id] = self
        objreg.register('main-window',
                        self,
                        scope='window',
                        window=self.win_id)
        tab_registry = objreg.ObjectRegistry()
        objreg.register('tab-registry',
                        tab_registry,
                        scope='window',
                        window=self.win_id)

        self.setWindowTitle('qutebrowser')
        self._vbox = QVBoxLayout(self)
        self._vbox.setContentsMargins(0, 0, 0, 0)
        self._vbox.setSpacing(0)

        self._init_downloadmanager()
        self._downloadview = downloadview.DownloadView(
            model=self._download_model)

        self.is_private = config.val.content.private_browsing or private

        self.tabbed_browser: tabbedbrowser.TabbedBrowser = tabbedbrowser.TabbedBrowser(
            win_id=self.win_id, private=self.is_private, parent=self)
        objreg.register('tabbed-browser',
                        self.tabbed_browser,
                        scope='window',
                        window=self.win_id)
        self._init_command_dispatcher()

        # We need to set an explicit parent for StatusBar because it does some
        # show/hide magic immediately which would mean it'd show up as a
        # window.
        self.status = bar.StatusBar(win_id=self.win_id,
                                    private=self.is_private,
                                    parent=self)

        self._add_widgets()
        self._downloadview.show()

        self._init_completion()

        log.init.debug("Initializing modes...")
        modeman.init(win_id=self.win_id, parent=self)

        self._commandrunner = runners.CommandRunner(self.win_id,
                                                    partial_match=True)

        self._keyhint = keyhintwidget.KeyHintView(self.win_id, self)
        self._add_overlay(self._keyhint, self._keyhint.update_geometry)

        self._prompt_container = prompt.PromptContainer(self.win_id, self)
        self._add_overlay(self._prompt_container,
                          self._prompt_container.update_geometry,
                          centered=True,
                          padding=10)
        objreg.register('prompt-container',
                        self._prompt_container,
                        scope='window',
                        window=self.win_id,
                        command_only=True)
        self._prompt_container.hide()

        self._messageview = messageview.MessageView(parent=self)
        self._add_overlay(self._messageview, self._messageview.update_geometry)

        self._xkb_switch = xkbswitch.XkbSwitchPlugin(win_id=self.win_id,
                                                     parent=self)

        self._init_geometry(geometry)
        self._connect_signals()

        # When we're here the statusbar might not even really exist yet, so
        # resizing will fail. Therefore, we use singleShot QTimers to make sure
        # we defer this until everything else is initialized.
        QTimer.singleShot(0, self._connect_overlay_signals)
        config.instance.changed.connect(self._on_config_changed)

        objects.qapp.new_window.emit(self)
        self._set_decoration(config.val.window.hide_decoration)

        self.state_before_fullscreen = self.windowState()
        stylesheet.set_register(self)

        global i3ipc_used
        if i3ipc_used:
            try:
                self.wm_connection = WMConnection()
                response = self.wm_connection.get_version()
                self.wm_variant = 'i3'
                if 'variant' in response.ipc_data and response.ipc_data[
                        'variant'] == 'sway':
                    self.wm_variant = 'sway'
            except:
                i3ipc_used = False

    def _init_geometry(self, geometry):
        """Initialize the window geometry or load it from disk."""
        if geometry is not None:
            self._load_geometry(geometry)
        elif self.win_id == 0:
            self._load_state_geometry()
        else:
            self._set_default_geometry()
        log.init.debug("Initial main window geometry: {}".format(
            self.geometry()))

    def _add_overlay(self, widget, signal, *, centered=False, padding=0):
        self._overlays.append((widget, signal, centered, padding))

    def _update_overlay_geometries(self):
        """Update the size/position of all overlays."""
        for w, _signal, centered, padding in self._overlays:
            self._update_overlay_geometry(w, centered, padding)

    def _update_overlay_geometry(self, widget, centered, padding):
        """Reposition/resize the given overlay."""
        if not widget.isVisible():
            return

        if widget.sizePolicy().horizontalPolicy() == QSizePolicy.Expanding:
            width = self.width() - 2 * padding
            if widget.hasHeightForWidth():
                height = widget.heightForWidth(width)
            else:
                height = widget.sizeHint().height()
            left = padding
        else:
            size_hint = widget.sizeHint()
            width = min(size_hint.width(), self.width() - 2 * padding)
            height = size_hint.height()
            left = (self.width() - width) // 2 if centered else 0

        height_padding = 20
        status_position = config.val.statusbar.position
        if status_position == 'bottom':
            if self.status.isVisible():
                status_height = self.status.height()
                bottom = self.status.geometry().top()
            else:
                status_height = 0
                bottom = self.height()
            top = self.height() - status_height - height
            top = qtutils.check_overflow(top, 'int', fatal=False)
            topleft = QPoint(left, max(height_padding, top))
            bottomright = QPoint(left + width, bottom)
        elif status_position == 'top':
            if self.status.isVisible():
                status_height = self.status.height()
                top = self.status.geometry().bottom()
            else:
                status_height = 0
                top = 0
            topleft = QPoint(left, top)
            bottom = status_height + height
            bottom = qtutils.check_overflow(bottom, 'int', fatal=False)
            bottomright = QPoint(left + width,
                                 min(self.height() - height_padding, bottom))
        else:
            raise ValueError("Invalid position {}!".format(status_position))

        rect = QRect(topleft, bottomright)
        log.misc.debug('new geometry for {!r}: {}'.format(widget, rect))
        if rect.isValid():
            widget.setGeometry(rect)

    def _init_downloadmanager(self):
        log.init.debug("Initializing downloads...")
        qtnetwork_download_manager = objreg.get('qtnetwork-download-manager')

        try:
            webengine_download_manager = objreg.get(
                'webengine-download-manager')
        except KeyError:
            webengine_download_manager = None

        self._download_model = downloads.DownloadModel(
            qtnetwork_download_manager, webengine_download_manager)
        objreg.register('download-model',
                        self._download_model,
                        scope='window',
                        window=self.win_id,
                        command_only=True)

    def _init_completion(self):
        self._completion = completionwidget.CompletionView(cmd=self.status.cmd,
                                                           win_id=self.win_id,
                                                           parent=self)
        completer_obj = completer.Completer(cmd=self.status.cmd,
                                            win_id=self.win_id,
                                            parent=self._completion)
        self._completion.selection_changed.connect(
            completer_obj.on_selection_changed)
        objreg.register('completion',
                        self._completion,
                        scope='window',
                        window=self.win_id,
                        command_only=True)
        self._add_overlay(self._completion, self._completion.update_geometry)

    def _init_command_dispatcher(self):
        # Lazy import to avoid circular imports
        from qutebrowser.browser import commands
        self._command_dispatcher = commands.CommandDispatcher(
            self.win_id, self.tabbed_browser)
        objreg.register('command-dispatcher',
                        self._command_dispatcher,
                        command_only=True,
                        scope='window',
                        window=self.win_id)

        widget = self.tabbed_browser.widget
        widget.destroyed.connect(
            functools.partial(objreg.delete,
                              'command-dispatcher',
                              scope='window',
                              window=self.win_id))

    def __repr__(self):
        return utils.get_repr(self)

    @pyqtSlot(str)
    def _on_config_changed(self, option):
        """Resize the completion if related config options changed."""
        if option == 'statusbar.padding':
            self._update_overlay_geometries()
        elif option == 'downloads.position':
            self._add_widgets()
        elif option == 'statusbar.position':
            self._add_widgets()
            self._update_overlay_geometries()
        elif option == 'window.hide_decoration':
            self._set_decoration(config.val.window.hide_decoration)

    def _add_widgets(self):
        """Add or readd all widgets to the VBox."""
        self._vbox.removeWidget(self.tabbed_browser.widget)
        self._vbox.removeWidget(self._downloadview)
        self._vbox.removeWidget(self.status)
        widgets: List[QWidget] = [self.tabbed_browser.widget]

        downloads_position = config.val.downloads.position
        if downloads_position == 'top':
            widgets.insert(0, self._downloadview)
        elif downloads_position == 'bottom':
            widgets.append(self._downloadview)
        else:
            raise ValueError("Invalid position {}!".format(downloads_position))

        status_position = config.val.statusbar.position
        if status_position == 'top':
            widgets.insert(0, self.status)
        elif status_position == 'bottom':
            widgets.append(self.status)
        else:
            raise ValueError("Invalid position {}!".format(status_position))

        for widget in widgets:
            self._vbox.addWidget(widget)

    def _load_state_geometry(self):
        """Load the geometry from the state file."""
        try:
            data = configfiles.state['geometry']['mainwindow']
            geom = base64.b64decode(data, validate=True)
        except KeyError:
            # First start
            self._set_default_geometry()
        except binascii.Error:
            log.init.exception("Error while reading geometry")
            self._set_default_geometry()
        else:
            self._load_geometry(geom)

    def _save_geometry(self):
        """Save the window geometry to the state config."""
        data = self.saveGeometry().data()
        geom = base64.b64encode(data).decode('ASCII')
        configfiles.state['geometry']['mainwindow'] = geom

    def _load_geometry(self, geom):
        """Load geometry from a bytes object.

        If loading fails, loads default geometry.
        """
        log.init.debug("Loading mainwindow from {!r}".format(geom))
        ok = self.restoreGeometry(geom)
        if not ok:
            log.init.warning("Error while loading geometry.")
            self._set_default_geometry()

    def _connect_overlay_signals(self):
        """Connect the resize signal and resize everything once."""
        for widget, signal, centered, padding in self._overlays:
            signal.connect(
                functools.partial(self._update_overlay_geometry, widget,
                                  centered, padding))
            self._update_overlay_geometry(widget, centered, padding)

    def _set_default_geometry(self):
        """Set some sensible default geometry."""
        self.setGeometry(QRect(50, 50, 800, 600))

    def _connect_signals(self):
        """Connect all mainwindow signals."""
        mode_manager = modeman.instance(self.win_id)

        # misc
        self.tabbed_browser.close_window.connect(self.close)
        mode_manager.entered.connect(hints.on_mode_entered)

        # status bar
        mode_manager.hintmanager.set_text.connect(self.status.set_text)
        mode_manager.entered.connect(self.status.on_mode_entered)
        mode_manager.left.connect(self.status.on_mode_left)
        mode_manager.left.connect(self.status.cmd.on_mode_left)
        mode_manager.left.connect(message.global_bridge.mode_left)

        # xkbswitch
        mode_manager.entered.connect(self._xkb_switch.on_mode_entered)
        mode_manager.left.connect(self._xkb_switch.on_mode_left)

        # commands
        mode_manager.keystring_updated.connect(
            self.status.keystring.on_keystring_updated)
        self.status.cmd.got_cmd[str].connect(self._commandrunner.run_safely)
        self.status.cmd.got_cmd[str,
                                int].connect(self._commandrunner.run_safely)
        self.status.cmd.returnPressed.connect(
            self.tabbed_browser.on_cmd_return_pressed)
        self.status.cmd.got_search.connect(self._command_dispatcher.search)

        # key hint popup
        mode_manager.keystring_updated.connect(self._keyhint.update_keyhint)

        # messages
        message.global_bridge.show_message.connect(
            self._messageview.show_message)
        message.global_bridge.flush()
        message.global_bridge.clear_messages.connect(
            self._messageview.clear_messages)

        # statusbar
        self.tabbed_browser.current_tab_changed.connect(
            self.status.on_tab_changed)

        self.tabbed_browser.cur_progress.connect(
            self.status.prog.on_load_progress)
        self.tabbed_browser.cur_load_started.connect(
            self.status.prog.on_load_started)

        self.tabbed_browser.cur_scroll_perc_changed.connect(
            self.status.percentage.set_perc)
        self.tabbed_browser.widget.tab_index_changed.connect(
            self.status.tabindex.on_tab_index_changed)

        self.tabbed_browser.cur_url_changed.connect(self.status.url.set_url)
        self.tabbed_browser.cur_url_changed.connect(
            functools.partial(self.status.backforward.on_tab_cur_url_changed,
                              tabs=self.tabbed_browser))
        self.tabbed_browser.cur_link_hovered.connect(
            self.status.url.set_hover_url)
        self.tabbed_browser.cur_load_status_changed.connect(
            self.status.url.on_load_status_changed)

        self.tabbed_browser.cur_caret_selection_toggled.connect(
            self.status.on_caret_selection_toggled)

        self.tabbed_browser.cur_fullscreen_requested.connect(
            self._on_fullscreen_requested)
        self.tabbed_browser.cur_fullscreen_requested.connect(
            self.status.maybe_hide)

        # downloadview
        self.tabbed_browser.cur_fullscreen_requested.connect(
            self._downloadview.on_fullscreen_requested)

        # command input / completion
        mode_manager.entered.connect(self.tabbed_browser.on_mode_entered)
        mode_manager.left.connect(self.tabbed_browser.on_mode_left)
        self.status.cmd.clear_completion_selection.connect(
            self._completion.on_clear_completion_selection)
        self.status.cmd.hide_completion.connect(self._completion.hide)

    def _set_decoration(self, hidden):
        """Set the visibility of the window decoration via Qt."""
        window_flags: int = Qt.Window
        refresh_window = self.isVisible()
        if hidden:
            window_flags |= Qt.CustomizeWindowHint | Qt.NoDropShadowWindowHint
        self.setWindowFlags(cast(Qt.WindowFlags, window_flags))
        if refresh_window:
            self.show()

    @pyqtSlot(bool)
    def _on_fullscreen_requested(self, on):
        if not config.val.content.fullscreen.window:
            if on:
                self.state_before_fullscreen = self.windowState()
                self.setWindowState(
                    Qt.WindowFullScreen |  # type: ignore[arg-type]
                    self.state_before_fullscreen)  # type: ignore[operator]
            elif self.isFullScreen():
                self.setWindowState(self.state_before_fullscreen)
        log.misc.debug('on: {}, state before fullscreen: {}'.format(
            on, debug.qflags_key(Qt, self.state_before_fullscreen)))

    @cmdutils.register(instance='main-window', scope='window')
    @pyqtSlot()
    def close(self):
        """Close the current window.

        //

        Extend close() so we can register it as a command.
        """
        super().close()

    def resizeEvent(self, e):
        """Extend resizewindow's resizeEvent to adjust completion.

        Args:
            e: The QResizeEvent
        """
        super().resizeEvent(e)
        self._update_overlay_geometries()
        self._downloadview.updateGeometry()
        self.tabbed_browser.widget.tabBar().refresh()

    def showEvent(self, e):
        """Extend showEvent to register us as the last-visible-main-window.

        Args:
            e: The QShowEvent
        """
        super().showEvent(e)
        objreg.register('last-visible-main-window', self, update=True)

    def _confirm_quit(self):
        """Confirm that this window should be closed.

        Return:
            True if closing is okay, False if a closeEvent should be ignored.
        """
        tab_count = self.tabbed_browser.widget.count()
        download_count = self._download_model.running_downloads()
        quit_texts = []
        # Ask if multiple-tabs are open
        if 'multiple-tabs' in config.val.confirm_quit and tab_count > 1:
            quit_texts.append("{} tabs are open.".format(tab_count))
        # Ask if multiple downloads running
        if 'downloads' in config.val.confirm_quit and download_count > 0:
            quit_texts.append("{} {} running.".format(
                download_count,
                "download is" if download_count == 1 else "downloads are"))
        # Process all quit messages that user must confirm
        if quit_texts or 'always' in config.val.confirm_quit:
            msg = jinja.environment.from_string("""
                <ul>
                {% for text in quit_texts %}
                   <li>{{text}}</li>
                {% endfor %}
                </ul>
            """.strip()).render(quit_texts=quit_texts)
            confirmed = message.ask('Really quit?',
                                    msg,
                                    mode=usertypes.PromptMode.yesno,
                                    default=True)

            # Stop asking if the user cancels
            if not confirmed:
                log.destroy.debug("Cancelling closing of window {}".format(
                    self.win_id))
                return False

        return True

    def closeEvent(self, e):
        """Override closeEvent to display a confirmation if needed."""
        if crashsignal.crash_handler.is_crashing:
            e.accept()
            return

        if not self._confirm_quit():
            e.ignore()
            return

        e.accept()

        for key in ['last-visible-main-window', 'last-focused-main-window']:
            try:
                win = objreg.get(key)
                if self is win:
                    objreg.delete(key)
            except KeyError:
                pass

        sessions.session_manager.save_last_window_session()
        self._save_geometry()

        # Wipe private data if we close the last private window, but there are
        # still other windows
        if (self.is_private and len(objreg.window_registry) > 1 and len([
                window for window in objreg.window_registry.values()
                if window.is_private
        ]) == 1):
            log.destroy.debug("Wiping private data before closing last "
                              "private window")
            websettings.clear_private_data()

        log.destroy.debug("Closing window {}".format(self.win_id))
        self.tabbed_browser.shutdown()
示例#12
0
#!/usr/bin/env python

from i3ipc import Connection
import re

conn = Connection()
ps = conn.get_tree().find_classed("Blueberry.py")

killed = False
for p in ps:
    if re.findall("on", p.floating):
        p.command('kill')
        killed = True

if not killed:
    conn.command('exec blueberry')
示例#13
0
def main(args):
    '''Connect to IPC, set transparencies, and set up listener'''
    ipc = Connection()
    for window in ipc.get_tree():
        if args.all or window.focused:
            window.command('opacity ' + args.opacity)
示例#14
0
#!/usr/bin/env python3

from i3ipc import Connection
import stash

if __name__ == "__main__":

    i3 = Connection()

    workspace = i3.get_tree().find_focused().workspace().name

    if stash.is_minor(workspace):
        i3.command("move container to workspace %s" % stash.major(workspace))
    else:
        i3.command("move container to workspace %s" % stash.minor(workspace))
示例#15
0
#!/usr/bin/env python3
from i3ipc import Connection
from subprocess import call

# This shows i3 keybind actions with a notification.
# It can be useful as an alternative to showkey.

i3 = Connection()

def notify(i3, event):
	# print(event.binding.__dict__)
	bind = event.binding

	mods_dict = [
		['Mod4', 'Super'],
		['shift', 'Shift'],
		['ctrl', 'Control'],
		['Mod1', 'Alt'],
	]
	mods = '+'.join([
		mod[1]
		for mod in mods_dict
		if mod[0] in bind.mods
	])
	if mods: mods += '+'

	call('notify-send -t 1000 -a i3wm'.split(' ')
		+ [bind.command, '%s%s' % (mods, bind.symbol)]
	)

i3.on('binding', notify)
示例#16
0
def load_i3_layout(json_url):
    from i3ipc import Connection, Event

    _download(json_url, "/tmp/layout.json")
    i3 = Connection()
    i3.command("workspace 1; append_layout /tmp/layout.json")
示例#17
0
        bar_pid = bar.start_bar()
        lemonbar.set_outputs()
        lemonbar.render_all(caller=caller, e=data)

    i3.on('workspace::urgent', lemonbar.on_workspace_event)
    i3.on('workspace::empty', lemonbar.on_workspace_event)
    if display_title:
        i3.on('window::title', lemonbar.on_window_title_change)
        i3.on('window::close', lemonbar.on_window_close)
        i3.on('window::focus', lemonbar.on_window_title_change)
        i3.on('workspace::focus', lemonbar.on_workspace_focus)
    else:
        i3.on('workspace::focus', lemonbar.on_workspace_event)
    i3.on('mode', lemonbar.on_binding_mode_change)
    i3.on('output', reload_bar)
    i3.on('shutdown', shutdown)
    i3.main()


bar = Bar()
parse_opt()
i3 = Connection(socket_path=socket)
bar.set_config(i3)

if not debug:
    wbak = dup(1)
    bar_pid = bar.start_bar()
else:
    print(bar.bar_args)
run()
示例#18
0
)
parser.add_argument(
	'-s', '--shorten',
	action='store',
	type=int,
	default=-1,
	dest='shorten',
	help='shorten names to this length, 0 for no limit',
)

args = parser.parse_args()
opts = args.__dict__



i3 = Connection()

layouts = {
	'splith': 'H',
	'splitv': 'V',
	'stacked': 'S',
	'tabbed': 'T',
}

def parse_tree(con):
	if opts['pango']:
		foc_pre = '<u>'
		foc_pst = '</u>'
	else:
		foc_pre = '*'
		foc_pst = '*'
示例#19
0
class I3ipc(Ipc):
    """
    i3ipc - an improved python library to control i3wm and sway
    """

    _focused_workspace = None
    _focused_window = None

    def setup(self, parent):
        from threading import Thread

        self.parent.cache_timeout = self.parent.py3.CACHE_FOREVER
        self.window_properties = {}

        t = Thread(target=self.start)
        t.daemon = True
        t.start()

    # noinspection PyTypeChecker
    def start(self):
        from i3ipc import Connection, Event

        self.i3 = Connection()

        self._update(self.i3.get_tree().find_focused())

        self.i3.on(Event.WORKSPACE_FOCUS, self._on_workplace_focus)
        self.i3.on(Event.WINDOW_CLOSE, self._on_window_close)
        self.i3.on(Event.WINDOW_TITLE, self._on_window_title)
        self.i3.on(Event.WINDOW_FOCUS, self._on_window_focus)
        self.i3.on(Event.BINDING, self._on_binding)
        self.i3.main()

    def _on_workplace_focus(self, i3, event):
        self._focused_workspace = event.current
        self._focused_window = None
        if event.current.nodes or event.current.floating_nodes:
            return
        self._update(event.current)

    def _on_window_close(self, i3, event):
        if event.container.window == self._focused_window:
            self._focused_window = None
            self._update(i3.get_tree().find_focused())

    def _on_binding(self, i3, event):
        self._update(i3.get_tree().find_focused())

    def _on_window_title(self, i3, event):
        if event.container.focused:
            self._update(event.container)

    def _on_window_focus(self, i3, event):
        self._focused_window = event.container.window
        self._update(event.container)

    def _update(self, event_element):
        if not event_element:
            return

        # hide title on containers with window title
        if self.parent.hide_title:
            show_name = True
            if event_element.border == "normal" or event_element.type == "workspace":
                show_name = False
            else:
                event_element_parent = event_element.parent or getattr(
                    self.i3.get_tree().find_by_id(event_element.id), "parent",
                    None)
                if (event_element_parent and event_element_parent.layout
                        in ("stacked", "tabbed")
                        and len(event_element_parent.nodes) > 1):
                    show_name = False

            window_properties = {
                "title": event_element.name if show_name else None,
                "class": event_element.window_class,
                "instance": event_element.window_instance,
            }

        else:
            window_properties = {
                "title": event_element.name,
                "class": event_element.window_class,
                "instance": event_element.window_instance,
            }

        window_properties = self.compatibility(window_properties)

        if self.window_properties != window_properties:
            self.window_properties = window_properties
            self.parent.py3.update()

    def get_window_properties(self):
        return self.window_properties
示例#20
0
def main(args):
    i3 = Connection()
    i3.on(Event.WINDOW_NEW, on_window_new)

    with Listener(on_click=on_click):
        i3.main()
示例#21
0
 def __init__(self):
     self.i3 = Connection() # Create the Connection object that can be used to send commands and subscribe
     self.updateWinState()
示例#22
0
def set_ws(ws):
    i3 = Connection()
    i3.command(f'workspace number {ws}')
示例#23
0
    def __init__(self):
        self.floating_windows = []
        self.fader_running = False
        self.fade_queue = []
        self.fade_data = {}
        self.bottom_win = None
        self.old_win = None
        self.active_win = None

        ipc = Connection()
        ipc.on(Event.WINDOW_FOCUS, self.on_window_focus)
        ipc.on(Event.WINDOW_NEW, self.on_window_new)
        ipc.on(Event.WINDOW_FLOATING, self.on_window_floating)

        for win in ipc.get_tree():
            if win.type == "floating_con":
                self.floating_windows.append(win.id)
                if win.focused:
                    change_opacity(win, FLOAT_AC)
                    self.active_win = win
                else:
                    change_opacity(win, FLOAT_INAC)
            elif win.type == "con":
                if win.focused:
                    self.active_win = win
                    change_opacity(win, CON_AC)
                else:
                    change_opacity(win, CON_INAC)

        ipc.main()
示例#24
0
#!/usr/bin/env python3
#
# Promotes the focused window by swapping it with the largest window.

from i3ipc import Connection, Event


def find_biggest_window(container):
    max_leaf = None
    max_area = 0
    for leaf in container.leaves():
        rect = leaf.rect
        area = rect.width * rect.height
        if not leaf.focused and area > max_area:
            max_area = area
            max_leaf = leaf
    return max_leaf


i3 = Connection()

for reply in i3.get_workspaces():
    if reply.focused:
        workspace = i3.get_tree().find_by_id(reply.ipc_data["id"])
        master = find_biggest_window(workspace)
        i3.command("swap container with con_id %s" % master.id)
#!/usr/bin/env python
from i3ipc import Connection
from notify2 import Notification, init
from psutil import Process

# This script only works with 'real' local terminals within Sway.
# We need to gracefully exit if using ssh, local console or a multiplexer.

multiplexers = ("tmux: server", "screen")

# determine if we can connect to ipc and get status
try:
    i3 = Connection()
# we won't get a status over ssh, via local console or not running i3/Sway
except Exception:
    exit()

# verify if running Sway
if "sway" not in i3.socket_path:
    exit()

p = Process()
# I am sure there is a better way to loop through all the parent processes
# names and make sure they aren't a multiplexer
for parent in p.parents():
    if parent.name() in multiplexers:
        exit()

# get terminal pid
terminal_pid = p.parents()[-2].pid
示例#26
0
    for i in range(len(con.nodes)):
        if con.nodes[i].id == new_con.id:
            child = i

    if not child:
        return

    dest = 2 if child == 1 else 1
    if con.nodes[dest].layout == 'splith':
        con.nodes[dest].command('split v')
    move_con(new_con, dest - child)


def new_move_callback(self, e):
    def get_workspace(cnx, e):
        return cnx.get_tree().find_by_id(e.container.id).workspace()

    cnx = Connection()
    wsp = get_workspace(cnx, e)
    if not wsp:
        # This removes problems on i3 start
        return
    new_con = wsp.find_by_id(e.container.id)
    place_node(cnx, wsp, new_con)


i3 = Connection()
i3.on('window::new', new_move_callback)
i3.on('window::move', new_move_callback)
i3.main()
示例#27
0
    def __init__(self):
        self.fader_running = False
        self.fade_queue = []
        self.fade_data = {}
        self.current_win = None
        self.new_win = None

        ipc = Connection()
        ipc.on(Event.WINDOW_FOCUS, self.on_window_focus)
        ipc.on(Event.WINDOW_NEW, self.on_window_new)
        ipc.on(Event.WINDOW_FLOATING, self.on_window_floating)

        for win in ipc.get_tree():
            if win.focused:
                change_opacity(win, AC_TRANS)
                self.current_win = win
            else:
                change_opacity(win, INAC_TRANS)

        ipc.main()
示例#28
0
#!/usr/bin/python

from i3ipc import Connection
import sys

i3 = Connection()

current = i3.get_tree().find_focused()
window_rect = current.window_rect
workspace = current.workspace()

print("workspace width => %d" % workspace.rect.width)
print("workspace height => %d" % workspace.rect.height)

print("window width => %d" % window_rect.width)
print("window height => %d" % window_rect.height)


def change_size(direction: str, target_size_str: str):

    if direction == 'width':
        current_screen_size = workspace.rect.width
        current_window_size = window_rect.width
    else:
        current_screen_size = workspace.rect.height
        current_window_size = window_rect.height

    if '%' in target_size_str:
        target_size = int(current_screen_size *
                          (float(target_size_str.replace('%', '')) / 100))
    else:
示例#29
0
#!/usr/bin/env python3

sway = False

if sway:
    from i3ipc import Connection
    i3 = Connection()
ipc_data = None

outputs = {}
windows_list = []
taskbars_list = []
controls_list = []
config_dir = ""
app_dirs = []

key_missing = False

dependencies = {
    "pyalsa": False,
    "upower": False,
    "acpi": False,
    "netifaces": False,
}

icons_path = ""  # "icons_light", "icons_dark" or "" (GTK icons)

commands = {
    "get_battery":
    "upower -i $(upower -e | grep BAT) | grep --color=never -E 'state|to\\\\ full|to\\\\ empty|percentage'",
    "get_battery_alt": "acpi",
示例#30
0
#!/usr/bin/env python3
from datetime import datetime
from i3ipc import Connection
from os import system
#https://github.com/altdesktop/i3ipc-python

i3 = Connection()
focused = i3.get_tree().find_focused()
name, workspace = focused.name, focused.workspace().name
if len(name) > 40: name = name[:48] + '...'
system('notify-send -t 1000 "{}" "{}"'.format(workspace, name))
示例#31
0
#!/usr/bin/env python3
import os
from i3ipc import Connection, Event

i3 = Connection()


def on_workspace_focus(self, e):
    if e.current:
        os.system("dunstify -r 10551 workspace " + e.current.name)


i3.on(Event.WORKSPACE_FOCUS, on_workspace_focus)
i3.main()
示例#32
0
#!/usr/bin/env python3

# budRich@budlabs - 2019
#
# this will make all new windows floating
# due to the way i3 handles for_window rules
# setting a "global rule" to make all new
# windows floating, may have undesired side effects.
#
# https://github.com/i3/i3/issues/3628
# https://github.com/i3/i3/pull/3188
# https://old.reddit.com/r/i3wm/comments/85ctji/when_windows_are_floating_by_default_how_do_i/

from i3ipc import Connection
i3 = Connection()


def set_floating(i3, event):
    event.container.command('floating enable')


i3.on('window::new', set_floating)
i3.main()
示例#33
0
def main():
    i3 = Connection()
    handler = I3UnityFix()
    i3.on(Event.WORKSPACE_FOCUS, handler.on_workspace_focus)
    i3.main()
示例#34
0
from i3ipc import Connection
from subprocess import call


def window_notify(i3, event):
    if event.container.fullscreen_mode == 0:
        call ('polybar-msg cmd show'.split())
    else:
        call ('polybar-msg cmd hide'.split())

    if event.change in ["focus", "title"]:
        call("polybar-msg hook titlehook 1".split(" "))


def window_ws_notify(i3, event):
    if event.change in ["title", "focus"]:
        call('polybar-msg hook wshook 1'.split())


def ws_notify(i3, event):
    if event.change == "focus":
        if event.old.num != -1:
            call('polybar-msg hook wshook 1'.split())


if __name__ == "__main__":
    i3 = Connection()
    i3.on('window', window_ws_notify)
    i3.on('workspace', window_ws_notify)
    i3.main()
示例#35
0
#!/usr/bin/env python2

from i3ipc import Connection
from workspacer import get_current_workspace_num, get_workspace_names
from sys import argv
import subprocess

if __name__ == "__main__":
    con = Connection()
    names = get_workspace_names(con)
    current_num = get_current_workspace_num(con)
    if current_num in names:
        current_name = names[current_num]
    else:
        current_name = current_num
    p = subprocess.Popen(["dmenu", "-p","{}:".format(current_name)], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    p.stdin.close()
    newname = p.stdout.read().strip()
    if newname:
        con.command("rename workspace to {}:{}".format(current_num,newname))
    else:
        con.command("rename workspace to {}".format(current_num))