Skip to content
Snippets Groups Projects
Verified Commit 641eedf9 authored by Pascal Ernster's avatar Pascal Ernster :mask:
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
README 0 → 100644
This project was inspired by crussh (https://github.com/nergdron/crussh).
However, since crussh is written in Python2, which will be EOLed in the foreseeable future, and because I wanted an easy project to play around with Python (3), I've started this project.
Don't sell it, and don't redistribute it without attribution.
crassh.py 0 → 100755
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, Gio
gi.require_version('Vte', '2.91')
from gi.repository import Vte, GLib
import sys
# https://bugzilla.gnome.org/show_bug.cgi?id=622084#c12
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
from pathlib import Path
import configparser
config = configparser.ConfigParser()
configpath = "{0}/.config/crassh/crassh.cfg".format(Path.home())
config.read(configpath)
class CrasshWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="crassh")
header = Gtk.HeaderBar(title="crassh")
header.set_subtitle("Many connections, much ssh")
header.props.show_close_button = True
button_add = Gtk.Button()
button_add.add(Gtk.Image.new_from_gicon(Gio.ThemedIcon(name="list-add-symbolic"), Gtk.IconSize.BUTTON))
def add_ssh_host_dialog(widget, event):
AddSshHostDialog(self)
button_add.connect("button-release-event", add_ssh_host_dialog)
header.pack_start(button_add)
button_settings = Gtk.Button()
button_settings.add(Gtk.Image.new_from_gicon(Gio.ThemedIcon(name="preferences-system-symbolic"), Gtk.IconSize.BUTTON))
def settings_dialog(widget, event):
dialog = SettingsDialog(self)
response = dialog.run()
if response == Gtk.ResponseType.APPLY:
print("The apply button was clicked")
dialog.apply_settings()
elif response == Gtk.ResponseType.CANCEL:
print("The Cancel button was clicked")
dialog.destroy()
button_settings.connect("button-release-event", settings_dialog)
header.pack_start(button_settings)
self.set_titlebar(header)
grid = Gtk.Grid()
self.add(grid)
scrolled = Gtk.ScrolledWindow()
scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
grid.attach_next_to(scrolled, None, Gtk.PositionType.BOTTOM, 1, 1)
self.flowbox = Gtk.FlowBox(expand=True, homogeneous=True, column_spacing=1, row_spacing=1, selection_mode=Gtk.SelectionMode.NONE)
self.flowbox.set_min_children_per_line(5)
self.flowbox.set_max_children_per_line(10)
self.entry = Gtk.Entry(hexpand=True,vexpand=False)
# feed GNOME clipboard to all active terminals
def feed_paste(widget):
def multiplex(flowboxchild):
terminal = flowboxchild.get_child()
terminal.paste_clipboard()
self.flowbox.foreach(multiplex)
widget.set_text("")
# this stops regular handler from firing, switching focus.
return True
def feed_input(widget, event):
def multiplex(flowboxchild):
terminal = flowboxchild.get_child()
t_event = event.copy()
terminal.event(t_event)
self.flowbox.foreach(multiplex)
widget.set_text("")
# this stops regular handler from firing, switching focus.
return True
def click_handler(widget, event):
# if middle click
if event.button == 2:
feed_input(widget, event)
self.entry.connect("key_press_event", feed_input)
self.entry.connect("key_release_event", feed_input)
self.entry.connect("paste_clipboard", feed_paste)
self.entry.connect("button_press_event", click_handler)
grid.attach_next_to(self.entry, scrolled, Gtk.PositionType.BOTTOM, 1, 1)
hosts = sys.argv[1:]
for host in hosts:
self.add_ssh_host(self.flowbox, host)
self.entry.grab_focus()
scrolled.add(self.flowbox)
self.show_all()
def add_ssh_host(self, flowbox, host):
terminal = Vte.Terminal(expand=True)
terminal.connect("child-exited", self.remove_ssh_host, host)
self.flowbox.add(terminal)
print("Connecting to", host)
terminal.spawn_sync(Vte.PtyFlags.DEFAULT, None, ['ssh', host, None], None, GLib.SpawnFlags.DEFAULT|GLib.SpawnFlags.SEARCH_PATH, None, None, None)
terminal.show()
def remove_ssh_host(self, widget, exitcode, host):
print("Disconnected from", host)
self.flowbox.remove(widget.get_parent())
if 0 == len(self.flowbox.get_children()):
Gtk.main_quit()
class AddSshHostDialog(Gtk.Dialog):
def __init__(self, parent):
def click_handler(widget):
for host in widget.get_text().split():
win.add_ssh_host(win.flowbox, host)
self.close();
#Gtk.Dialog.__init__(self, "Add SSH hosts", parent, 0,
# (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
# Gtk.STOCK_OK, Gtk.ResponseType.OK))
Gtk.Dialog.__init__(self, "Add SSH hosts", parent, 0, None)
label = Gtk.Label("Please enter the additional SSH hosts to connect to:")
entry = Gtk.Entry(hexpand=True,vexpand=False)
entry.connect("activate", click_handler)
box = self.get_content_area()
box.add(label)
box.add(entry)
self.show_all()
class SettingsDialog(Gtk.Dialog):
def __init__(self, parent):
def apply_settings(widget):
#win.flowbox.set_min_children_per_line(int(widget.get_text()))
win.flowbox.set_min_children_per_line(int(spinbutton_minperline.get_text()))
win.flowbox.set_max_children_per_line(int(spinbutton_maxperline.get_text()))
Gtk.Dialog.__init__(self, "Settings", parent, 0,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_APPLY, Gtk.ResponseType.APPLY))
#Gtk.Dialog.__init__(self, "Settings", parent, 0, None)
label_minperline = Gtk.Label("Minimal number of terminals per line:")
adjustment_minperline = Gtk.Adjustment(0, 0, 100, 1, 10, 0)
spinbutton_minperline = Gtk.SpinButton(numeric=True, hexpand=True, vexpand=False, adjustment=adjustment_minperline)
spinbutton_minperline.set_range(1,65535)
spinbutton_minperline.connect("activate", apply_settings)
label_maxperline = Gtk.Label("Maximal number of terminals per line:")
adjustment_maxperline = Gtk.Adjustment(0, 0, 100, 1, 10, 0)
spinbutton_maxperline = Gtk.SpinButton(numeric=True, hexpand=True, vexpand=False, adjustment=adjustment_maxperline)
spinbutton_maxperline.set_range(1,65535)
spinbutton_maxperline.connect("activate", apply_settings)
box = self.get_content_area()
box.add(label_minperline)
box.add(spinbutton_minperline)
box.add(label_maxperline)
box.add(spinbutton_maxperline)
self.show_all()
win = CrasshWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment