Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions INSTALL
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Installation Instructions
*************************

Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
Inc.

Copying and distribution of this file, with or without modification,
Expand All @@ -12,8 +12,8 @@ without warranty of any kind.
Basic Installation
==================

Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
Briefly, the shell command `./configure && make && make install'
should configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
Expand Down Expand Up @@ -309,9 +309,10 @@ causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).

Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
an Autoconf limitation. Until the limitation is lifted, you can use
this workaround:

CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash

`configure' Invocation
======================
Expand Down Expand Up @@ -367,4 +368,3 @@ operates.

`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

4 changes: 4 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ DEPENDENCIES
* python-dbus
* python-gconf
* python-xdg
* python-wnck

To build guake, you will need the following packages too:
* python-dev
Expand All @@ -58,6 +59,9 @@ Under Debian/Ubuntu, the following command should install all the build
dependencies:
sudo apt-get build-dep guake

You will also need libgconf2-dev library in Ubuntu
sudo apt-get install libgconf2-dev


INSTALLATION
~~~~~~~~~~~~
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ if test x"$GCONFTOOL" = xno; then
AC_MSG_ERROR([gconftool-2 executable not found in your path - should be installed with GConf])
fi
AM_GCONF_SOURCE_2
AM_PROG_AR

dnl Internationalization
GETTEXT_PACKAGE=guake
Expand Down
12 changes: 12 additions & 0 deletions data/guake.schemas
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@
</locale>
</schema>

<schema>
<key>/schemas/apps/guake/general/window_monitor</key>
<applyto>/apps/guake/general/window_monitor</applyto>
<owner>guake</owner>
<type>int</type>
<default>0</default>
<locale name="C">
<short>Window position on multirples monitors.</short>
<long>Window position behavior in multiples monitors.</long>
</locale>
</schema>

<schema>
<key>/schemas/apps/guake/general/use_login_shell</key>
<applyto>/apps/guake/general/use_login_shell</applyto>
Expand Down
35 changes: 35 additions & 0 deletions data/prefs.glade
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,41 @@
<property name="visible">True</property>
<property name="spacing">6</property>
<property name="homogeneous">True</property>
<child>
<widget class="GtkHBox" id="hbox5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<widget class="GtkLabel" id="lblChooseWindowMonitor1">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Appeares on monitor:</property>
</widget>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="window_monitor">
<property name="visible">True</property>
<property name="items" translatable="yes"/>
<signal name="changed" handler="on_window_monitor_changed" swapped="no"/>
</widget>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="window_ontop">
<property name="label" translatable="yes">Stay on top</property>
Expand Down
139 changes: 125 additions & 14 deletions src/guake
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pygtk.require('2.0')
gobject.threads_init()

import gtk
import glib
import vte
from pango import FontDescription
import pynotify
Expand All @@ -43,6 +44,7 @@ from time import sleep
import posix
from urllib import url2pathname
from urlparse import urlsplit
import wnck

import guake.globalhotkeys
from guake.simplegladeapp import SimpleGladeApp, bindtextdomain
Expand Down Expand Up @@ -128,6 +130,7 @@ class GConfHandler(object):
notify_add(KEY('/general/show_resizer'), self.show_resizer_toggled)

notify_add(KEY('/general/use_trayicon'), self.trayicon_toggled)
notify_add(KEY('/general/window_monitor'), self.alignment_changed)
notify_add(KEY('/general/window_ontop'), self.ontop_toggled)
notify_add(KEY('/general/window_tabbar'), self.tabbar_toggled)
notify_add(KEY('/general/window_height'), self.size_changed)
Expand Down Expand Up @@ -624,6 +627,14 @@ class Guake(SimpleGladeApp):
# resizer stuff
self.resizer.connect('motion-notify-event', self.on_resizer_drag)

# Workspaces tracking
self.boxes_by_workspaces = {}
# 0 = hidden, 1 = shown, 2 = fullscreen hidden, 3 = fullscreen shown
self.state_by_workspaces = {}
self.active_by_workspaces = {}
self.screen = wnck.screen_get_default()
self.screen.connect( "active-workspace-changed", self.workspace_changed )

# adding the first tab on guake
self.add_tab()

Expand Down Expand Up @@ -659,6 +670,59 @@ class Guake(SimpleGladeApp):
'press <b>%s</b> to use it.') % label, filename)
notification.show()

def workspace_changed(self, screen, previous_workspace):

workspace = self.screen.get_active_workspace()

w_num = workspace.get_number()

self.current_workspace = w_num

if previous_workspace:
prev_w_num = previous_workspace.get_number()
self.active_by_workspaces[prev_w_num] = self.get_active_box()
if prev_w_num != w_num:
# Workspace did change
for box, bnt in self.boxes_by_workspaces[prev_w_num]:
box.hide()
bnt.hide()
if not w_num in self.boxes_by_workspaces:
# New workspace - hence empty
self.add_tab()
else:
for box, bnt in self.boxes_by_workspaces[w_num]:
box.show()
bnt.show()
if w_num not in self.state_by_workspaces:
# Never shown in this workspace
self.state_by_workspaces[w_num] = 0
new_wp_state = self.state_by_workspaces[w_num]
if new_wp_state % 2:
self.set_active_box(self.active_by_workspaces[w_num])
self.show()
else:
self.hide()
if new_wp_state < 2 and self.is_fullscreen:
self.unfullscreen()
elif new_wp_state >= 2 and not self.is_fullscreen:
self.fullscreen()
self.set_terminal_focus()
else:
# guake just started - so it is invisible
self.state_by_workspaces[w_num] = 0

def get_active_box(self):
"""Return the currently shown GuakeTerminalBox.
"""
page_num = self.notebook.get_current_page()
return self.notebook.get_nth_page(page_num)

def set_active_box(self, box):
"""Show the given GuakeTerminalBox.
"""
page_num = self.notebook.page_num(box)
self.notebook.set_current_page(page_num)

def execute_command(self, command, tab=None):
"""Execute the `command' in the `tab'. If tab is None, the
command will be executed in the currently selected
Expand Down Expand Up @@ -785,6 +849,7 @@ class Guake(SimpleGladeApp):
def show(self):
"""Shows the main window and grabs the focus on it.
"""

# setting window in all desktops
self.get_widget('window-root').stick()

Expand All @@ -793,7 +858,12 @@ class Guake(SimpleGladeApp):
if not self.term_list:
self.add_tab()

self.window.show_all()
self.window.set_keep_below(False)
# move to the active monitor first (with the extra pixel)
# so the window will appears correctly after show it
window_rect = self.get_final_window_rect()
self.window.move(window_rect.x + 1, window_rect.y + 1)
self.window.show()
self.client.notify(KEY('/general/window_height'))

try:
Expand All @@ -809,39 +879,51 @@ class Guake(SimpleGladeApp):
# after the widget is shown.
self.client.notify(KEY('/style/font/color'))
self.client.notify(KEY('/style/background/color'))
fullscreen = self.state_by_workspaces[self.current_workspace] >= 2
state = 1 + fullscreen * 2
self.state_by_workspaces[self.current_workspace] = state

def hide(self):
"""Hides the main window of the terminal and sets the visible
flag to False.
"""
self.window.set_keep_below(True)
self.window.hide() # Don't use hide_all here!
fullscreen = self.state_by_workspaces[self.current_workspace] >= 2
state = fullscreen * 2
self.state_by_workspaces[self.current_workspace] = state

def get_final_window_rect(self):
"""Gets the final size of the main window of guake. The height
is the window_height property, width is window_width and the
horizontal alignment is given by window_alignment.
"""
screen = self.window.get_screen()
screen = gtk.gdk.screen_get_default()
display = gtk.gdk.display_get_default()
pointer = display.get_pointer()
window_monitor = self.client.get_int(KEY('/general/window_monitor'))

height = self.client.get_int(KEY('/general/window_height'))
width = 100
halignment = self.client.get_int(KEY('/general/window_halignment'))

# get the rectangle just from the first/default monitor in the
# future we might create a field to select which monitor you
# wanna use
window_rect = screen.get_monitor_geometry(0)
monitor_num = 0
if window_monitor == 1:
monitor_num = screen.get_monitor_at_point(pointer[1], pointer[2])
elif window_monitor > 1:
monitor_num = window_monitor - 2
window_rect = screen_rect = screen.get_monitor_geometry(monitor_num)
total_width = window_rect.width
window_rect.height = window_rect.height * height / 100
window_rect.width = window_rect.width * width / 100

if width < total_width:
if halignment == ALIGN_CENTER:
window_rect.x = (total_width - window_rect.width) / 2
window_rect.x = screen_rect.x + (total_width - window_rect.width) / 2
elif halignment == ALIGN_LEFT:
window_rect.x = 0
window_rect.x = screen_rect.x
elif halignment == ALIGN_RIGHT:
window_rect.x = total_width - window_rect.width
window_rect.y = 0
window_rect.x = screen_rect.x + total_width - window_rect.width
window_rect.y = screen_rect.y
return window_rect

def get_running_fg_processes(self):
Expand All @@ -866,6 +948,7 @@ class Guake(SimpleGladeApp):
"""
self.client.notify(KEY('/general/use_trayicon'))
self.client.notify(KEY('/general/prompt_on_quit'))
self.client.notify(KEY('/general/window_monitor'))
self.client.notify(KEY('/general/window_tabbar'))
self.client.notify(KEY('/general/window_ontop'))
self.client.notify(KEY('/general/window_height'))
Expand Down Expand Up @@ -967,6 +1050,8 @@ class Guake(SimpleGladeApp):
def fullscreen(self):
self.window.fullscreen()
self.is_fullscreen = True
if self.state_by_workspaces[self.current_workspace] < 2:
self.state_by_workspaces[self.current_workspace] += 2

# The resizer widget really don't need to be shown in
# fullscreen mode, but tabbar will only be shown if a
Expand All @@ -978,6 +1063,8 @@ class Guake(SimpleGladeApp):
def unfullscreen(self):
self.window.unfullscreen()
self.is_fullscreen = False
if self.state_by_workspaces[self.current_workspace] > 2:
self.state_by_workspaces[self.current_workspace] -= 2

# making sure that tabbar and resizer will come back to
# their default state.
Expand Down Expand Up @@ -1233,21 +1320,45 @@ class Guake(SimpleGladeApp):
self.notebook.set_current_page(self.notebook.page_num(box))
box.terminal.grab_focus()
self.load_config()

# If the program is just starting, wnck is still not ready to give us
# the workspace - so use idle_add:
glib.idle_add(self.assign_workspace, box, bnt)

def assign_workspace(self, box, bnt):
w = self.screen.get_active_workspace()
w_num = w.get_number()

if not w_num in self.boxes_by_workspaces:
self.boxes_by_workspaces[w_num] = []

self.boxes_by_workspaces[w_num].append( (box, bnt) )

def delete_tab(self, pagepos, kill=True):
"""This function will destroy the notebook page, terminal and
tab widgets and will call the function to kill interpreter
forked by vte.
"""
self.tabs.get_children()[pagepos].destroy()
self.notebook.remove_page(pagepos)
tab = self.tabs.get_children()[pagepos]

current_boxes = self.boxes_by_workspaces[self.current_workspace]
for rel_pos in range(len(current_boxes)):
box, bnt = current_boxes[rel_pos]
if bnt is tab:
current_boxes.pop(rel_pos)
box.destroy()
bnt.destroy()
break

self.term_list.pop(pagepos).destroy()
pid = self.pid_list.pop(pagepos)

if kill:
start_new_thread(self.delete_shell, (pid,))

if not self.term_list:

if not self.boxes_by_workspaces[self.current_workspace]:
# No more boxes in current workspace
self.hide()
# avoiding the delay on next Guake show request
self.add_tab()
Expand Down
Loading