Exemplo n.º 1
0
    def __init__ (self):
        global lookingGlassProxy
        lookingGlassProxy = LookingGlassProxy()
        self.lookingGlassProxy = lookingGlassProxy
        lookingGlassProxy.addStatusChangeCallback(self.setStatus)

        self.window = None
        self.run()

        dbus.service.Object.__init__ (self, dbus.SessionBus (), MELANGE_DBUS_PATH, MELANGE_DBUS_NAME)
Exemplo n.º 2
0
    def __init__ (self):
        global lookingGlassProxy
        lookingGlassProxy = LookingGlassProxy()
        self.lookingGlassProxy = lookingGlassProxy
        # The status label is shown iff we are not okay
        lookingGlassProxy.addStatusChangeCallback(lambda x: self.statusLabel.set_visible(not x))

        self.window = None
        self.run()

        dbus.service.Object.__init__ (self, dbus.SessionBus (), MELANGE_DBUS_PATH, MELANGE_DBUS_NAME)
Exemplo n.º 3
0
    def __init__(self):
        global lookingGlassProxy
        lookingGlassProxy = LookingGlassProxy()
        self.lookingGlassProxy = lookingGlassProxy
        lookingGlassProxy.addStatusChangeCallback(self.setStatus)

        self.window = None
        self.run()

        dbus.service.Object.__init__(self, dbus.SessionBus(),
                                     MELANGE_DBUS_PATH, MELANGE_DBUS_NAME)
Exemplo n.º 4
0
    def __init__ (self):
        global lookingGlassProxy
        lookingGlassProxy = LookingGlassProxy()
        self.lookingGlassProxy = lookingGlassProxy
        # The status label is shown iff we are not okay
        lookingGlassProxy.addStatusChangeCallback(lambda x: self.statusLabel.set_visible(not x))

        self.window = None
        self.run()

        dbus.service.Object.__init__ (self, dbus.SessionBus (), MELANGE_DBUS_PATH, MELANGE_DBUS_NAME)
Exemplo n.º 5
0
    def __init__(self):
        self.lg_proxy = LookingGlassProxy()
        # The status label is shown iff we are not okay
        self.lg_proxy.add_status_change_callback(
            lambda x: self.status_label.set_visible(not x))

        self.window = None
        self._minimized = False
        self.run()

        dbus.service.Object.__init__(self, dbus.SessionBus(),
                                     MELANGE_DBUS_PATH, MELANGE_DBUS_NAME)
Exemplo n.º 6
0
    def __init__(self):
        self.lg_proxy = LookingGlassProxy()
        # The status label is shown iff we are not okay
        self.lg_proxy.add_status_change_callback(lambda x: self.status_label.set_visible(not x))

        self.window = None
        self._minimized = False
        self.run()

        dbus.service.Object.__init__(self, dbus.SessionBus(), MELANGE_DBUS_PATH, MELANGE_DBUS_NAME)
Exemplo n.º 7
0
class MelangeApp(dbus.service.Object):
    def __init__(self):
        self.lg_proxy = LookingGlassProxy()
        # The status label is shown iff we are not okay
        self.lg_proxy.add_status_change_callback(
            lambda x: self.status_label.set_visible(not x))

        self.window = None
        self._minimized = False
        self.run()

        dbus.service.Object.__init__(self, dbus.SessionBus(),
                                     MELANGE_DBUS_PATH, MELANGE_DBUS_NAME)

    @dbus.service.method(MELANGE_DBUS_NAME, in_signature='', out_signature='')
    def show(self):
        if self.window.get_visible():
            if self._minimized:
                self.window.present()
            else:
                self.window.hide()
        else:
            self.show_and_focus()

    @dbus.service.method(MELANGE_DBUS_NAME, in_signature='', out_signature='')
    def hide(self):
        self.window.hide()

    @dbus.service.method(MELANGE_DBUS_NAME, in_signature='', out_signature='b')
    def getVisible(self):
        return self.window.get_visible()

    @dbus.service.method(MELANGE_DBUS_NAME, in_signature='', out_signature='')
    def doInspect(self):
        if self.lg_proxy:
            self.lg_proxy.StartInspector()
            self.window.hide()

    def show_and_focus(self):
        self.window.show_all()
        self.lg_proxy.refresh_status()
        self.command_line.grab_focus()

    def run(self):
        self.window = Gtk.Window(type=Gtk.WindowType.TOPLEVEL)
        self.window.set_title("Melange")
        self.window.set_icon_name("system-search")
        self.window.set_default_size(1000, 400)
        self.window.set_position(Gtk.WindowPosition.MOUSE)

        # I can't think of a way to reliably detect if the window
        # is active to determine if we need to present or hide
        # in show(). Since the window briefly loses focus during
        # shortcut press we'd be unable to detect it at that time.
        # Keeping the window on top ensures the window is never
        # obscured so we can just hide if visible.
        self.window.set_keep_above(True)

        self.window.connect("delete_event", self.on_delete)
        self.window.connect("key-press-event", self.on_key_press)
        self._minimized = False
        self.window.connect("window-state-event", self.on_window_state)

        num_rows = 3
        num_columns = 6
        table = Gtk.Table(n_rows=num_rows,
                          n_columns=num_columns,
                          homogeneous=False)
        table.set_margin_start(6)
        table.set_margin_end(6)
        table.set_margin_top(6)
        table.set_margin_bottom(6)
        self.window.add(table)

        self.notebook = Gtk.Notebook()
        self.notebook.set_tab_pos(Gtk.PositionType.BOTTOM)
        self.notebook.show()
        self.notebook.set_show_border(True)
        self.notebook.set_show_tabs(True)

        label = Gtk.Label(label="Melange")
        label.set_markup("<u>Melange - Cinnamon Debugger</u> ")
        label.show()
        self.notebook.set_action_widget(label, Gtk.PackType.END)

        self.pages = {}
        self.custom_pages = {}
        self.create_page("Results", "results")
        self.create_page("Inspect", "inspect")
        self.create_page("Windows", "windows")
        self.create_page("Extensions", "extensions")
        self.create_page("Log", "log")

        table.attach(self.notebook, 0, num_columns, 0, 1)

        column = 0
        picker_button = pageutils.ImageButton("color-select-symbolic")
        picker_button.set_tooltip_text("Select an actor to inspect")
        picker_button.connect("clicked", self.on_picker_clicked)
        table.attach(picker_button, column, column + 1, 1, 2, 0, 0, 2)
        column += 1

        full_gc = pageutils.ImageButton("user-trash-full-symbolic")
        full_gc.set_tooltip_text("Invoke garbage collection")
        # ignore signal arg
        full_gc.connect('clicked', lambda source: self.lg_proxy.FullGc())
        table.attach(full_gc, column, column + 1, 1, 2, 0, 0, 2)
        column += 1

        self.command_line = CommandLine(self.lg_proxy.Eval)
        self.command_line.set_tooltip_text("Evaluate javascript")
        table.attach(self.command_line, column, column + 1, 1, 2,
                     Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, 0, 3,
                     2)
        column += 1

        self.status_label = Gtk.Label(label="Status")
        self.status_label.set_markup(
            " <span foreground='red'>[ Cinnamon is OFFLINE! ]</span> ")
        self.status_label.set_tooltip_text(
            "The connection to cinnamon is broken")
        self.status_label.set_no_show_all(True)
        table.attach(self.status_label, column, column + 1, 1, 2, 0, 0, 1)
        column += 1

        box = Gtk.HBox()
        settings = Gio.Settings(schema="org.cinnamon.desktop.keybindings")
        arr = settings.get_strv("looking-glass-keybinding")
        if len(arr) > 0:
            # only the first mapped keybinding
            [accel_key, mask] = Gtk.accelerator_parse(arr[0])
            if accel_key == 0 and mask == 0:
                # failed to parse, fallback to plain accel string
                label = Gtk.Label(label=arr[0])
            else:
                label = Gtk.Label(
                    label=Gtk.accelerator_get_label(accel_key, mask))
            label.set_tooltip_text("Toggle shortcut")
            box.pack_start(label, False, False, 3)

        action_button = self.create_action_button()
        box.pack_start(action_button, False, False, 3)

        table.attach(box, column, column + 1, 1, 2, 0, 0, 1)

        self.activate_page("results")
        self.status_label.hide()
        self.window.set_focus(self.command_line)

    def create_menu_item(self, text, callback):
        item = Gtk.MenuItem(label=text)
        item.connect("activate", callback)
        return item

    def create_action_button(self):
        restart_func = lambda junk: os.system(
            "nohup cinnamon --replace > /dev/null 2>&1 &")
        crash_func = lambda junk: self.lg_proxy.Eval("global.segfault()")

        menu = Gtk.Menu()
        menu.append(
            self.create_menu_item('Add File Watcher',
                                  self.on_add_file_watcher))
        menu.append(Gtk.SeparatorMenuItem())
        menu.append(self.create_menu_item('Restart Cinnamon', restart_func))
        menu.append(self.create_menu_item('Crash Cinnamon', crash_func))
        menu.append(
            self.create_menu_item('Reset Cinnamon Settings',
                                  self.on_reset_clicked))
        menu.append(Gtk.SeparatorMenuItem())
        menu.append(
            self.create_menu_item('About Melange', self.on_about_clicked))
        menu.append(self.create_menu_item('Quit', self.on_delete))
        menu.show_all()

        button = Gtk.MenuButton(label="Actions \u25BE")
        button.set_popup(menu)
        return button

    def on_add_file_watcher(self, menu_item):
        dialog = NewLogDialog(self.window)
        response = dialog.run()

        if response == Gtk.ResponseType.OK and dialog.is_valid():
            label = ClosableTabLabel(dialog.get_text())
            content = FileWatcherView(dialog.get_file())
            content.show()
            label.connect("close-clicked", self.on_close_tab, content)
            self.custom_pages[label] = content
            self.notebook.append_page(content, label)
            self.notebook.set_current_page(self.notebook.get_n_pages() - 1)

        dialog.destroy()

    def on_close_tab(self, label, content):
        self.notebook.remove_page(self.notebook.page_num(content))
        content.destroy()
        del self.custom_pages[label]

    def on_about_clicked(self, menu_item):
        dialog = Gtk.MessageDialog(self.window, 0, Gtk.MessageType.QUESTION,
                                   Gtk.ButtonsType.CLOSE)

        dialog.set_title("About Melange")
        dialog.set_markup("""\
<b>Melange</b> is a GTK3 alternative to the built-in javascript debugger <i>Looking Glass</i>

Pressing <i>Escape</i> while Melange has focus will hide the window.
If you want to exit Melange, use ALT+F4 or the <u>Actions</u> menu button.

If you defined a hotkey for Melange, pressing it while Melange is visible it will be hidden."""
                          )

        dialog.run()
        dialog.destroy()

    def on_reset_clicked(self, menu_item):
        dialog = Gtk.MessageDialog(self.window, 0, Gtk.MessageType.WARNING,
                                   Gtk.ButtonsType.YES_NO,
                                   "Reset all cinnamon settings to default?")
        dialog.set_title("Warning: Trying to reset all cinnamon settings!")

        response = dialog.run()
        dialog.destroy()
        if response == Gtk.ResponseType.YES:
            os.system("gsettings reset-recursively org.cinnamon &")

    def on_key_press(self, widget, event=None):
        if event.keyval == Gdk.KEY_Escape:
            self.window.hide()

    def on_delete(self, widget=None, event=None):
        tmp_pages = self.custom_pages.copy()
        for label, content in tmp_pages.items():
            self.on_close_tab(label, content)
        Gtk.main_quit()
        return False

    def on_window_state(self, widget, event):
        if event.new_window_state & Gdk.WindowState.ICONIFIED:
            self._minimized = True
        else:
            self._minimized = False

    def on_picker_clicked(self, widget):
        self.lg_proxy.StartInspector()
        self.window.hide()

    def create_dummy_page(self, text, description):
        label = Gtk.Label(label=text)
        self.notebook.append_page(Gtk.Label(label=description), label)

    def create_page(self, text, module_name):
        module = __import__("page_%s" % module_name)
        module.lg_proxy = self.lg_proxy
        module.melangeApp = self
        label = Gtk.Label(label=text)
        page = module.ModulePage(self)
        self.pages[module_name] = page
        self.notebook.append_page(page, label)

    def activate_page(self, module_name):
        page = self.notebook.page_num(self.pages[module_name])
        self.notebook.set_current_page(page)
    def activatePage(self, moduleName):
        self.showAndFocus()
        page = self.notebook.page_num(self.pages[moduleName])
        self.notebook.set_current_page(page)

def setStatus(status):
    if status:
        statusLabel.hide()
    else:
        statusLabel.show()

if __name__ == "__main__":
    GObject.type_register(ResizeGrip)
    DBusGMainLoop(set_as_default=True)

    global lookingGlassProxy
    lookingGlassProxy = LookingGlassProxy()
    lookingGlassProxy.addStatusChangeCallback(setStatus)

    sessionBus = dbus.SessionBus ()
    request = sessionBus.request_name(MELANGE_DBUS_NAME, dbus.bus.NAME_FLAG_DO_NOT_QUEUE)
    if request != dbus.bus.REQUEST_NAME_REPLY_EXISTS:
        app = SagarmathaLog()
    else:
        object = sessionBus.get_object(MELANGE_DBUS_NAME, MELANGE_DBUS_PATH)
        app = dbus.Interface(object, MELANGE_DBUS_NAME)

    startInspector = len(sys.argv) == 2 and sys.argv[1] == 'inspect'
    app.show(startInspector)
Exemplo n.º 9
0
        page = self.notebook.page_num(self.pages[moduleName])
        self.notebook.set_current_page(page)


def setStatus(status):
    if status:
        statusLabel.hide()
    else:
        statusLabel.show()


if __name__ == "__main__":
    GObject.type_register(ResizeGrip)
    DBusGMainLoop(set_as_default=True)

    global lookingGlassProxy
    lookingGlassProxy = LookingGlassProxy()
    lookingGlassProxy.addStatusChangeCallback(setStatus)

    sessionBus = dbus.SessionBus()
    request = sessionBus.request_name(MELANGE_DBUS_NAME,
                                      dbus.bus.NAME_FLAG_DO_NOT_QUEUE)
    if request != dbus.bus.REQUEST_NAME_REPLY_EXISTS:
        app = SagarmathaLog()
    else:
        object = sessionBus.get_object(MELANGE_DBUS_NAME, MELANGE_DBUS_PATH)
        app = dbus.Interface(object, MELANGE_DBUS_NAME)

    startInspector = len(sys.argv) == 2 and sys.argv[1] == 'inspect'
    app.show(startInspector)
Exemplo n.º 10
0
class MelangeApp(dbus.service.Object):
    def __init__(self):
        self.lg_proxy = LookingGlassProxy()
        # The status label is shown iff we are not okay
        self.lg_proxy.add_status_change_callback(lambda x: self.status_label.set_visible(not x))

        self.window = None
        self._minimized = False
        self.run()

        dbus.service.Object.__init__(self, dbus.SessionBus(), MELANGE_DBUS_PATH, MELANGE_DBUS_NAME)

    @dbus.service.method(MELANGE_DBUS_NAME, in_signature='', out_signature='')
    def show(self):
        if self.window.get_visible():
            if self._minimized:
                self.window.present()
            else:
                self.window.hide()
        else:
            self.show_and_focus()

    @dbus.service.method(MELANGE_DBUS_NAME, in_signature='', out_signature='')
    def hide(self):
        self.window.hide()

    @dbus.service.method(MELANGE_DBUS_NAME, in_signature='', out_signature='b')
    def getVisible(self):
        return self.window.get_visible()

    @dbus.service.method(MELANGE_DBUS_NAME, in_signature='', out_signature='')
    def doInspect(self):
        if self.lg_proxy:
            self.lg_proxy.StartInspector()
            self.window.hide()

    def show_and_focus(self):
        self.window.show_all()
        self.lg_proxy.refresh_status()
        self.command_line.grab_focus()

    def run(self):
        self.window = Gtk.Window(type=Gtk.WindowType.TOPLEVEL)
        self.window.set_title("Melange")
        self.window.set_icon_name("system-search")
        self.window.set_default_size(1000, 400)
        self.window.set_position(Gtk.WindowPosition.MOUSE)

        # I can't think of a way to reliably detect if the window
        # is active to determine if we need to present or hide
        # in show(). Since the window briefly loses focus during
        # shortcut press we'd be unable to detect it at that time.
        # Keeping the window on top ensures the window is never
        # obscured so we can just hide if visible.
        self.window.set_keep_above(True)

        self.window.connect("delete_event", self.on_delete)
        self.window.connect("key-press-event", self.on_key_press)
        self._minimized = False
        self.window.connect("window-state-event", self.on_window_state)

        num_rows = 3
        num_columns = 6
        table = Gtk.Table(n_rows=num_rows, n_columns=num_columns, homogeneous=False)
        table.set_margin_start(6)
        table.set_margin_end(6)
        table.set_margin_top(6)
        table.set_margin_bottom(6)
        self.window.add(table)

        self.notebook = Gtk.Notebook()
        self.notebook.set_tab_pos(Gtk.PositionType.BOTTOM)
        self.notebook.show()
        self.notebook.set_show_border(True)
        self.notebook.set_show_tabs(True)

        label = Gtk.Label(label="Melange")
        label.set_markup("<u>Melange - Cinnamon Debugger</u> ")
        label.show()
        self.notebook.set_action_widget(label, Gtk.PackType.END)

        self.pages = {}
        self.custom_pages = {}
        self.create_page("Results", "results")
        self.create_page("Inspect", "inspect")
        self.create_page("Windows", "windows")
        self.create_page("Extensions", "extensions")
        self.create_page("Log", "log")

        table.attach(self.notebook, 0, num_columns, 0, 1)

        column = 0
        picker_button = pageutils.ImageButton("color-select-symbolic")
        picker_button.set_tooltip_text("Select an actor to inspect")
        picker_button.connect("clicked", self.on_picker_clicked)
        table.attach(picker_button, column, column+1, 1, 2, 0, 0, 2)
        column += 1

        full_gc = pageutils.ImageButton("user-trash-full-symbolic")
        full_gc.set_tooltip_text("Invoke garbage collection")
        # ignore signal arg
        full_gc.connect('clicked', lambda source: self.lg_proxy.FullGc())
        table.attach(full_gc, column, column+1, 1, 2, 0, 0, 2)
        column += 1

        self.command_line = CommandLine(self.lg_proxy.Eval)
        self.command_line.set_tooltip_text("Evaluate javascript")
        table.attach(self.command_line,
                     column,
                     column + 1,
                     1,
                     2,
                     Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL,
                     0,
                     3,
                     2)
        column += 1

        self.status_label = Gtk.Label(label="Status")
        self.status_label.set_markup(" <span foreground='red'>[ Cinnamon is OFFLINE! ]</span> ")
        self.status_label.set_tooltip_text("The connection to cinnamon is broken")
        self.status_label.set_no_show_all(True)
        table.attach(self.status_label, column, column+1, 1, 2, 0, 0, 1)
        column += 1

        box = Gtk.HBox()
        settings = Gio.Settings(schema="org.cinnamon.desktop.keybindings")
        arr = settings.get_strv("looking-glass-keybinding")
        if len(arr) > 0:
            # only the first mapped keybinding
            [accel_key, mask] = Gtk.accelerator_parse(arr[0])
            if accel_key == 0 and mask == 0:
                # failed to parse, fallback to plain accel string
                label = Gtk.Label(label=arr[0])
            else:
                label = Gtk.Label(label=Gtk.accelerator_get_label(accel_key, mask))
            label.set_tooltip_text("Toggle shortcut")
            box.pack_start(label, False, False, 3)

        action_button = self.create_action_button()
        box.pack_start(action_button, False, False, 3)

        table.attach(box, column, column+1, 1, 2, 0, 0, 1)

        self.activate_page("results")
        self.status_label.hide()
        self.window.set_focus(self.command_line)

    def create_menu_item(self, text, callback):
        item = Gtk.MenuItem(label=text)
        item.connect("activate", callback)
        return item

    def create_action_button(self):
        restart_func = lambda junk: os.system("nohup cinnamon --replace > /dev/null 2>&1 &")
        crash_func = lambda junk: self.lg_proxy.Eval("global.segfault()")

        menu = Gtk.Menu()
        menu.append(self.create_menu_item('Add File Watcher', self.on_add_file_watcher))
        menu.append(Gtk.SeparatorMenuItem())
        menu.append(self.create_menu_item('Restart Cinnamon', restart_func))
        menu.append(self.create_menu_item('Crash Cinnamon', crash_func))
        menu.append(self.create_menu_item('Reset Cinnamon Settings', self.on_reset_clicked))
        menu.append(Gtk.SeparatorMenuItem())
        menu.append(self.create_menu_item('About Melange', self.on_about_clicked))
        menu.append(self.create_menu_item('Quit', self.on_delete))
        menu.show_all()

        button = Gtk.MenuButton(label="Actions \u25BE")
        button.set_popup(menu)
        return button

    def on_add_file_watcher(self, menu_item):
        dialog = NewLogDialog(self.window)
        response = dialog.run()

        if response == Gtk.ResponseType.OK and dialog.is_valid():
            label = ClosableTabLabel(dialog.get_text())
            content = FileWatcherView(dialog.get_file())
            content.show()
            label.connect("close-clicked", self.on_close_tab, content)
            self.custom_pages[label] = content
            self.notebook.append_page(content, label)
            self.notebook.set_current_page(self.notebook.get_n_pages()-1)

        dialog.destroy()

    def on_close_tab(self, label, content):
        self.notebook.remove_page(self.notebook.page_num(content))
        content.destroy()
        del self.custom_pages[label]

    def on_about_clicked(self, menu_item):
        dialog = Gtk.MessageDialog(self.window, 0,
                                   Gtk.MessageType.QUESTION, Gtk.ButtonsType.CLOSE)

        dialog.set_title("About Melange")
        dialog.set_markup("""\
<b>Melange</b> is a GTK3 alternative to the built-in javascript debugger <i>Looking Glass</i>

Pressing <i>Escape</i> while Melange has focus will hide the window.
If you want to exit Melange, use ALT+F4 or the <u>Actions</u> menu button.

If you defined a hotkey for Melange, pressing it while Melange is visible it will be hidden.""")

        dialog.run()
        dialog.destroy()

    def on_reset_clicked(self, menu_item):
        dialog = Gtk.MessageDialog(self.window, 0,
                                   Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO,
                                   "Reset all cinnamon settings to default?")
        dialog.set_title("Warning: Trying to reset all cinnamon settings!")

        response = dialog.run()
        dialog.destroy()
        if response == Gtk.ResponseType.YES:
            os.system("gsettings reset-recursively org.cinnamon &")

    def on_key_press(self, widget, event=None):
        if event.keyval == Gdk.KEY_Escape:
            self.window.hide()

    def on_delete(self, widget=None, event=None):
        tmp_pages = self.custom_pages.copy()
        for label, content in tmp_pages.items():
            self.on_close_tab(label, content)
        Gtk.main_quit()
        return False

    def on_window_state(self, widget, event):
        if event.new_window_state & Gdk.WindowState.ICONIFIED:
            self._minimized = True
        else:
            self._minimized = False

    def on_picker_clicked(self, widget):
        self.lg_proxy.StartInspector()
        self.window.hide()

    def create_dummy_page(self, text, description):
        label = Gtk.Label(label=text)
        self.notebook.append_page(Gtk.Label(label=description), label)

    def create_page(self, text, module_name):
        module = __import__("page_%s" % module_name)
        module.lg_proxy = self.lg_proxy
        module.melangeApp = self
        label = Gtk.Label(label=text)
        page = module.ModulePage(self)
        self.pages[module_name] = page
        self.notebook.append_page(page, label)

    def activate_page(self, module_name):
        page = self.notebook.page_num(self.pages[module_name])
        self.notebook.set_current_page(page)