Skip to content

Commit

Permalink
Merge 4d596dc into 8f630ce
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonathan Haylett committed Nov 17, 2019
2 parents 8f630ce + 4d596dc commit 0072181
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 45 deletions.
1 change: 1 addition & 0 deletions i3_resurrect/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def read(workspace, directory, profile):
if profile is not None:
filename = f'{profile}_layout.json'
layout_file = Path(directory) / filename

layout = None
try:
layout = json.loads(layout_file.read_text())
Expand Down
3 changes: 2 additions & 1 deletion i3_resurrect/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ def restore_workspace(workspace, numeric, directory, profile, target):

if target != 'layout_only':
# Restore programs.
programs.restore(workspace, directory, profile)
saved_programs = programs.read(workspace, directory, profile)
programs.restore(workspace_name, saved_programs)


@main.command('ls')
Expand Down
111 changes: 67 additions & 44 deletions i3_resurrect/programs.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ def save(workspace, numeric, directory, profile):
filename = f'{profile}_programs.json'
programs_file = Path(directory) / filename

terminals = config.get('terminals', [])

# Print deprecation warning if using old dictionary method of writing
# window command mappings.
# TODO: Remove in 2.0.0
Expand All @@ -34,60 +32,23 @@ def save(workspace, numeric, directory, profile):
'is deprecated and will be removed in favour of the list method '
'in the next major version.')

# Loop through windows and save commands to launch programs on saved
# workspace.
programs = []
for (con, pid) in windows_in_workspace(workspace, numeric):
if pid == 0:
continue

# Get process info for the window.
procinfo = psutil.Process(pid)

# Create command to launch program.
command = get_window_command(
con['window_properties'],
procinfo.cmdline(),
)
if command in ([], ''):
continue

# Remove empty string arguments from command.
command = [arg for arg in command if arg != '']

try:
# Obtain working directory using psutil.
if con['window_properties']['class'] in terminals:
# If the program is a terminal emulator, get the working
# directory from its first subprocess.
working_directory = procinfo.children()[0].cwd()
else:
working_directory = procinfo.cwd()
except Exception:
working_directory = str(Path.home())

# Add the command to the list.
programs.append({
'command': command,
'working_directory': working_directory
})
programs = get_programs(workspace, numeric)

# Write list of commands to file as JSON.
with programs_file.open('w') as f:
f.write(json.dumps(programs, indent=2))


def restore(workspace, directory, profile):
def read(workspace, directory, profile):
"""
Restore the running programs from an i3 workspace.
Read saved programs file.
"""
workspace_id = util.filename_filter(workspace)
filename = f'workspace_{workspace_id}_programs.json'
if profile is not None:
filename = f'{profile}_programs.json'
programs_file = Path(directory) / filename

# Read saved programs file.
programs = None
try:
programs = json.loads(programs_file.read_text())
Expand All @@ -99,8 +60,20 @@ def restore(workspace, directory, profile):
util.eprint('Could not find saved programs for workspace '
f'"{workspace}"')
sys.exit(1)
return programs


for entry in programs:
def restore(workspace_name, saved_programs):
"""
Restore the running programs from an i3 workspace.
"""
# Remove already running programs from the list of program to restore.
running_programs = get_programs(workspace_name, False)
for program in running_programs:
saved_programs.remove(program)

i3 = i3ipc.Connection()
for entry in saved_programs:
cmdline = entry['command']
working_directory = entry['working_directory']

Expand All @@ -120,10 +93,60 @@ def restore(workspace, directory, profile):
command = cmdline

# Execute command via i3 exec.
i3 = i3ipc.Connection()
i3.command(f'exec cd "{working_directory}" && {command}')


def get_programs(workspace, numeric):
"""
Get running programs in specified workspace.
Args:
workspace: The workspace to search.
numeric: Identify workspace by number instead of name.
"""
# Loop through windows and save commands to launch programs on saved
# workspace.
programs = []
for (con, pid) in windows_in_workspace(workspace, numeric):
if pid == 0:
continue

# Get process info for the window.
procinfo = psutil.Process(pid)

# Create command to launch program.
command = get_window_command(
con['window_properties'],
procinfo.cmdline(),
)
if command in ([], ''):
continue

# Remove empty string arguments from command.
command = [arg for arg in command if arg != '']

terminals = config.get('terminals', [])

try:
# Obtain working directory using psutil.
if con['window_properties']['class'] in terminals:
# If the program is a terminal emulator, get the working
# directory from its first subprocess.
working_directory = procinfo.children()[0].cwd()
else:
working_directory = procinfo.cwd()
except Exception:
working_directory = str(Path.home())

# Add the command to the list.
programs.append({
'command': command,
'working_directory': working_directory
})

return programs


def windows_in_workspace(workspace, numeric):
"""
Generator to iterate over windows in a workspace.
Expand Down

0 comments on commit 0072181

Please sign in to comment.