Merge lp:~tualatrix/ibentu/gnome-terminal into lp:ibentu

Proposed by FJKong
Status: Needs review
Proposed branch: lp:~tualatrix/ibentu/gnome-terminal
Merge into: lp:ibentu
Diff against target: 453404 lines (+451801/-0) (has conflicts)
297 files modified
.pc/.version (+1/-0)
.pc/01_lpi.patch/configure.ac (+195/-0)
.pc/01_lpi.patch/src/terminal-window.c (+4026/-0)
.pc/01_lpi.patch/src/terminal.xml (+116/-0)
.pc/01_onlyshowin.patch/gnome-terminal.desktop.in.in (+14/-0)
.pc/02_add_transparency_properties.patch/src/gnome-terminal.schemas.in (+1302/-0)
.pc/02_add_transparency_properties.patch/src/profile-editor.c (+921/-0)
.pc/02_add_transparency_properties.patch/src/profile-preferences.glade (+2814/-0)
.pc/02_add_transparency_properties.patch/src/terminal-profile.c (+1690/-0)
.pc/02_add_transparency_properties.patch/src/terminal-profile.h (+191/-0)
.pc/02_add_transparency_properties.patch/src/terminal-screen.c (+2343/-0)
.pc/20_add_alt_screen_toggle_ui.patch/src/gnome-terminal.schemas.in (+1317/-0)
.pc/20_add_alt_screen_toggle_ui.patch/src/profile-editor.c (+932/-0)
.pc/20_add_alt_screen_toggle_ui.patch/src/profile-preferences.glade (+2833/-0)
.pc/20_add_alt_screen_toggle_ui.patch/src/terminal-profile.c (+1693/-0)
.pc/20_add_alt_screen_toggle_ui.patch/src/terminal-profile.h (+192/-0)
.pc/20_add_alt_screen_toggle_ui.patch/src/terminal-screen.c (+2375/-0)
.pc/applied-patches (+4/-0)
AUTHORS (+3/-0)
COPYING (+676/-0)
ChangeLog (+47086/-0)
ChangeLog.README (+16/-0)
ChangeLog.pre-2-23 (+4754/-0)
HACKING (+13/-0)
Makefile.am (+64/-0)
Makefile.in (+877/-0)
NEWS (+730/-0)
README (+19/-0)
aclocal.m4 (+10078/-0)
config.guess (+1501/-0)
config.h.in (+107/-0)
config.sub (+1705/-0)
configure (+16194/-0)
configure.ac (+196/-0)
debian/changelog (+1829/-0)
debian/compat (+1/-0)
debian/control (+65/-0)
debian/control.in (+60/-0)
debian/copyright (+43/-0)
debian/fonts.conf (+11/-0)
debian/gnome-terminal-data.debhelper.log (+1/-0)
debian/gnome-terminal-data.install (+7/-0)
debian/gnome-terminal.debhelper.log (+1/-0)
debian/gnome-terminal.install (+3/-0)
debian/gnome-terminal.links (+1/-0)
debian/gnome-terminal.manpages (+1/-0)
debian/gnome-terminal.menu (+6/-0)
debian/gnome-terminal.postinst (+13/-0)
debian/gnome-terminal.prerm (+10/-0)
debian/gnome-terminal.sgml (+223/-0)
debian/gnome-terminal.wrapper (+81/-0)
debian/gnome-terminal.xpm (+166/-0)
debian/patches/01_lpi.patch (+47/-0)
debian/patches/01_onlyshowin.patch (+11/-0)
debian/patches/02_add_transparency_properties.patch (+330/-0)
debian/patches/20_add_alt_screen_toggle_ui.patch (+148/-0)
debian/patches/series (+4/-0)
debian/rules (+21/-0)
debian/source/format (+1/-0)
debian/watch (+3/-0)
depcomp (+630/-0)
gnome-doc-utils.make (+655/-0)
gnome-terminal.desktop.in.in (+15/-0)
help/C/gnome-terminal.xml (+1140/-0)
help/C/legal.xml (+76/-0)
help/Makefile.am (+17/-0)
help/Makefile.in (+1173/-0)
help/bg/Makefile.am (+10/-0)
help/bg/Makefile.in (+573/-0)
help/bg/gnome-terminal-bg.omf (+18/-0)
help/bg/gnome-terminal.xml (+943/-0)
help/bg/legal.xml (+9/-0)
help/ca/ca.po (+1967/-0)
help/ca/gnome-terminal.xml (+963/-0)
help/cs/cs.po (+1916/-0)
help/cs/gnome-terminal.xml (+956/-0)
help/da/da.po (+1921/-0)
help/da/gnome-terminal.xml (+957/-0)
help/de/de.po (+2018/-0)
help/de/gnome-terminal.xml (+956/-0)
help/el/el.po (+1985/-0)
help/el/gnome-terminal.xml (+957/-0)
help/en_GB/en_GB.po (+1918/-0)
help/en_GB/gnome-terminal.xml (+957/-0)
help/es/es.po (+1982/-0)
help/es/gnome-terminal.xml (+956/-0)
help/fr/fr.po (+1979/-0)
help/fr/gnome-terminal.xml (+956/-0)
help/gnome-terminal.omf.in (+9/-0)
help/it/gnome-terminal.xml (+960/-0)
help/it/it.po (+2052/-0)
help/ja/Makefile.am (+10/-0)
help/ja/Makefile.in (+573/-0)
help/ja/gnome-terminal-ja.omf (+35/-0)
help/ja/gnome-terminal.xml (+1388/-0)
help/ja/legal.xml (+47/-0)
help/ko/gnome-terminal.xml (+965/-0)
help/ko/ko.po (+1824/-0)
help/oc/gnome-terminal.xml (+1184/-0)
help/oc/oc.po (+1532/-0)
help/pt_BR/gnome-terminal.xml (+960/-0)
help/pt_BR/pt_BR.po (+1203/-0)
help/ro/Makefile.am (+10/-0)
help/ro/Makefile.in (+573/-0)
help/ro/gnome-terminal-ro.omf (+35/-0)
help/ro/gnome-terminal.xml (+1403/-0)
help/ro/legal.xml (+70/-0)
help/ru/gnome-terminal.xml (+980/-0)
help/ru/ru.po (+1121/-0)
help/sv/gnome-terminal.xml (+963/-0)
help/sv/sv.po (+1160/-0)
help/uk/gnome-terminal.xml (+980/-0)
help/uk/uk.po (+1936/-0)
help/zh_CN/gnome-terminal.xml (+956/-0)
help/zh_CN/zh_CN.po (+1788/-0)
help/zh_TW/Makefile.am (+10/-0)
help/zh_TW/Makefile.in (+573/-0)
help/zh_TW/gnome-terminal-zh_TW.omf (+35/-0)
help/zh_TW/gnome-terminal.xml (+1212/-0)
help/zh_TW/legal.xml (+54/-0)
install-sh (+520/-0)
ltmain.sh (+8406/-0)
missing (+376/-0)
mkinstalldirs (+162/-0)
omf.make (+61/-0)
po/LINGUAS (+92/-0)
po/Makefile.in.in (+217/-0)
po/POTFILES.in (+28/-0)
po/POTFILES.skip (+12/-0)
po/am.po (+2483/-0)
po/ar.po (+2786/-0)
po/as.po (+2921/-0)
po/ast.po (+2438/-0)
po/az.po (+2719/-0)
po/be.po (+2496/-0)
po/be@latin.po (+2946/-0)
po/bg.po (+2707/-0)
po/bn.po (+2647/-0)
po/bn_IN.po (+2660/-0)
po/br.po (+2248/-0)
po/bs.po (+2760/-0)
po/ca.po (+3414/-0)
po/ca@valencia.po (+3383/-0)
po/cs.po (+2597/-0)
po/cy.po (+3117/-0)
po/da.po (+3329/-0)
po/de.po (+3078/-0)
po/dz.po (+2377/-0)
po/el.po (+2977/-0)
po/en@shaw.po (+2580/-0)
po/en_CA.po (+2777/-0)
po/en_GB.po (+3339/-0)
po/eo.po (+2405/-0)
po/es.po (+2922/-0)
po/et.po (+2153/-0)
po/eu.po (+2661/-0)
po/fa.po (+2823/-0)
po/fi.po (+3209/-0)
po/fr.po (+2741/-0)
po/fur.po (+2225/-0)
po/ga.po (+2302/-0)
po/gl.po (+2727/-0)
po/gu.po (+2634/-0)
po/he.po (+3302/-0)
po/hi.po (+2289/-0)
po/hr.po (+2704/-0)
po/hu.po (+2663/-0)
po/hy.po (+2048/-0)
po/id.po (+2660/-0)
po/it.po (+2720/-0)
po/ja.po (+2707/-0)
po/ka.po (+2786/-0)
po/kk.po (+2402/-0)
po/kn.po (+2670/-0)
po/ko.po (+2632/-0)
po/ku.po (+2542/-0)
po/lt.po (+3165/-0)
po/lv.po (+3188/-0)
po/mai.po (+2022/-0)
po/mg.po (+2897/-0)
po/mk.po (+2701/-0)
po/ml.po (+2649/-0)
po/mn.po (+2656/-0)
po/mr.po (+2612/-0)
po/ms.po (+2727/-0)
po/nb.po (+2671/-0)
po/nds.po (+2018/-0)
po/ne.po (+2553/-0)
po/nl.po (+3395/-0)
po/nn.po (+3078/-0)
po/oc.po (+2434/-0)
po/or.po (+2625/-0)
po/pa.po (+2642/-0)
po/pl.po (+2670/-0)
po/ps.po (+1721/-0)
po/pt.po (+3382/-0)
po/pt_BR.po (+2740/-0)
po/ro.po (+2648/-0)
po/ru.po (+2209/-0)
po/rw.po (+3088/-0)
po/si.po (+2502/-0)
po/sk.po (+2404/-0)
po/sl.po (+2219/-0)
po/sq.po (+2772/-0)
po/sr.po (+3370/-0)
po/sr@latin.po (+3370/-0)
po/sv.po (+2348/-0)
po/ta.po (+2643/-0)
po/te.po (+2620/-0)
po/th.po (+3247/-0)
po/tr.po (+2489/-0)
po/ug.po (+2678/-0)
po/uk.po (+2601/-0)
po/vi.po (+1957/-0)
po/wa.po (+2806/-0)
po/xh.po (+2850/-0)
po/zh_CN.po (+2553/-0)
po/zh_HK.po (+2664/-0)
po/zh_TW.po (+2800/-0)
src/Makefile.am (+205/-0)
src/Makefile.in (+1470/-0)
src/eggdesktopfile.c (+1510/-0)
src/eggdesktopfile.h (+160/-0)
src/eggshell.c (+114/-0)
src/eggshell.h (+40/-0)
src/eggsmclient-osx.c (+235/-0)
src/eggsmclient-private.h (+53/-0)
src/eggsmclient-win32.c (+353/-0)
src/eggsmclient-xsmp.c (+1405/-0)
src/eggsmclient.c (+610/-0)
src/eggsmclient.h (+123/-0)
src/encodings-dialog.glade (+296/-0)
src/extra-strings.c (+73/-0)
src/find-dialog.glade (+236/-0)
src/gnome-terminal.schemas.in (+1334/-0)
src/keybinding-editor.glade (+194/-0)
src/profile-editor.c (+937/-0)
src/profile-editor.h (+34/-0)
src/profile-manager.glade (+213/-0)
src/profile-new-dialog.glade (+261/-0)
src/profile-preferences.glade (+2854/-0)
src/skey-challenge.glade (+198/-0)
src/skey-popup.c (+228/-0)
src/skey-popup.h (+35/-0)
src/skey/Makefile.am (+60/-0)
src/skey/Makefile.in (+773/-0)
src/skey/btoe.c (+304/-0)
src/skey/btoe.h (+2/-0)
src/skey/md4.c (+335/-0)
src/skey/md4.h (+19/-0)
src/skey/md5.c (+67/-0)
src/skey/md5.h (+9/-0)
src/skey/sha1.c (+112/-0)
src/skey/sha1.h (+9/-0)
src/skey/skey.c (+37/-0)
src/skey/skey.h (+10/-0)
src/skey/skeyutil.c (+24/-0)
src/skey/skeyutil.h (+3/-0)
src/skey/test.c (+99/-0)
src/terminal-accels.c (+1012/-0)
src/terminal-accels.h (+35/-0)
src/terminal-app.c (+2116/-0)
src/terminal-app.h (+159/-0)
src/terminal-debug.c (+45/-0)
src/terminal-debug.h (+74/-0)
src/terminal-encoding.c (+614/-0)
src/terminal-encoding.h (+61/-0)
src/terminal-info-bar.c (+119/-0)
src/terminal-info-bar.h (+62/-0)
src/terminal-intl.h (+27/-0)
src/terminal-marshal.list (+1/-0)
src/terminal-options.c (+1396/-0)
src/terminal-options.h (+118/-0)
src/terminal-profile.c (+1697/-0)
src/terminal-profile.h (+193/-0)
src/terminal-screen-container.c (+409/-0)
src/terminal-screen-container.h (+69/-0)
src/terminal-screen.c (+2378/-0)
src/terminal-screen.h (+160/-0)
src/terminal-search-dialog.c (+378/-0)
src/terminal-search-dialog.h (+49/-0)
src/terminal-tab-label.c (+289/-0)
src/terminal-tab-label.h (+64/-0)
src/terminal-tabs-menu.c (+487/-0)
src/terminal-tabs-menu.h (+56/-0)
src/terminal-type-builtins.c.template (+45/-0)
src/terminal-type-builtins.h.template (+25/-0)
src/terminal-util.c (+1213/-0)
src/terminal-util.h (+117/-0)
src/terminal-version.h (+35/-0)
src/terminal-version.h.in (+35/-0)
src/terminal-window.c (+4047/-0)
src/terminal-window.h (+106/-0)
src/terminal.about (+5/-0)
src/terminal.c (+619/-0)
src/terminal.xml (+118/-0)
xmldocs.make (+101/-0)
Conflict adding file COPYING.  Moved existing file to COPYING.moved.
Conflict adding file debian.  Moved existing file to debian.moved.
To merge this branch: bzr merge lp:~tualatrix/ibentu/gnome-terminal
Reviewer Review Type Date Requested Status
Ding Zhou Pending
Review via email: mp+62622@code.launchpad.net
To post a comment you must log in.

Unmerged revisions

76. By Ding Zhou

Release gnome-terminal 2.32.0-0ubuntu2

75. By Ding Zhou

Add Search selection on Google support

74. By Chris Coulson

* New upstream version 2.32.0
* Drop 21_dont_crash_on_composite_change.patch - merged upstream

73. By Chris Coulson

* Fix LP: #633303 - gnome-terminal crashed with signal 5 in _XError()
  when Mutter is restarted. Make sure gnome-terminal sets _NET_WM_DESKTOP
  on the new X window, rather than the one that was destroyed previously
  - add debian/patches/21_dont_crash_on_composite_change.patch
  - update debian/patches/series

72. By Robert Ancell

* New upstream release
* debian/control:
  - Bump build-depend on libvte-dev

71. By Robert Ancell

* New upstream release
* debian/control:
  - Build-depend on dh-autoreconf
  - Bump build-depend on libglib2.0-dev, libgtk2.0-dev, libvte-dev,
    libgconf2-dev
* debian/rules:
  - Use autoreconf.mk

70. By Chris Coulson

* Fix LP: #549552 - solid colour BG is transparent. When set to solid,
  the terminal window inherits transparency from the GTK theme. Add
  a checkbutton in the Background tab of the preferences to inherit
  background settings from the theme to make it possible to choose
  a solid colour again (without having to select "Transparent" and
  then adjusting the slider to maximum)
  - update debian/patches/02_add_transparency_properties.patch

69. By Robert Ancell

* Merge with Debian unstable, remaining Ubuntu changes:
* debian/control.in:
  - Build depend on gnome-common for autotools
  - Build depend on liblaunchpad-integration-dev
  - Add Bzr link
  - Update replaces version on gnome-terminal-data
* debian/rules:
  - Run autotools on build
* debian/patches/01_lpi.patch:
  - Launchpad integration
* debian/patches/02_add_transparency_properties.patch:
  - This patch allows the background transparency to be controlled from
    the GTK theme (using "TerminalScreen::background-darkness"). In
    addition to this, the background colour and text colour are already
    themable from the GTK theme (by setting the "text[NORMAL]" and
    "base[NORMAL]" colours for the TerminalScreen class)
* debian/patches/20_add_alt_screen_toggle_ui.patch:
  - Hook new vte alternate screen scrolling toggle via UI
* debian/watch:
  - Watch for unstable versions

68. By Robert Ancell

* Merge with Debian unstable, remaining Ubuntu changes:
* debian/control.in:
  - Build depend on liblaunchpad-integration-dev
  - Build depend on gnome-common to run autoreconf
  - Add Bzr link
* debian/rules:
  - Run autoreconf on build
* debian/patches/01_lpi.patch:
  - LP integration
* debian/patches/02_add_transparency_properties.patch:
  - This patch allows the background transparency to be controlled from
    the GTK theme (using "TerminalScreen::background-darkness"). In
    addition to this, the background colour and text colour are already
    themable from the GTK theme (by setting the "text[NORMAL]" and
    "base[NORMAL]" colours for the TerminalScreen class)
* debian/patches/20_add_alt_screen_toggle_ui.patch:
  - Hook new vte alternate screen scrolling toggle via UI
* debian/watch:
  - Watch for unstable versions

67. By Chris Coulson

* Revert the previous changes to add a new profile, as changing
  the default profile on upgrade is suboptimal, and there are better
  ways to implement the visual changes
  - Removed patches:
    + 02_rename_default_profile.patch
    + 03_add_new_profiles_on_upgrade.patch
    + 04_change_fallback_profile.patch
  - Delete debian/gnome-terminal-ambiance.schemas
  - Delete ebian/gnome-termina-data.gconf-defaults
  - debian/rules:
    + Don't install custom schema
* Add debian/patches/02_add_transparency_properties.patch:
  - This patch allows the background transparency to be controlled from
    the GTK theme (using "TerminalScreen::background-darkness"). In
    addition to this, the background colour and text colour are already
    themable from the GTK theme (by setting the "text[NORMAL]" and
    "base[NORMAL]" colours for the TerminalScreen class)
* debian/gnome-terminal-data.postinst:
  - Fix up the system gconf defaults when upgrading from a previous
    unstable version which had the extra profile. Users upgrading from
    this will probably still need to remove the "Ambiance" profile
    manually from their configuration though (there's not an easy way
    to do this automatically, and it only affects users upgrading
    from previous unstable versions)
* This fixes LP: #532511 and LP: #542144

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory '.pc'
=== added file '.pc/.version'
--- .pc/.version 1970-01-01 00:00:00 +0000
+++ .pc/.version 2011-05-27 08:11:08 +0000
@@ -0,0 +1,1 @@
12
02
=== added directory '.pc/01_lpi.patch'
=== added file '.pc/01_lpi.patch/configure.ac'
--- .pc/01_lpi.patch/configure.ac 1970-01-01 00:00:00 +0000
+++ .pc/01_lpi.patch/configure.ac 2011-05-27 08:11:08 +0000
@@ -0,0 +1,195 @@
1m4_define([gt_version_major],[2])
2m4_define([gt_version_minor],[32])
3m4_define([gt_version_micro],[0])
4m4_define([gt_version_extra],[])
5m4_define([gt_version],[gt_version_major().gt_version_minor().gt_version_micro()gt_version_extra])
6
7m4_define([gt_api_version],[0])
8
9AC_INIT([GNOME Terminal],[gt_version],[http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-terminal],[gnome-terminal])
10AC_CONFIG_SRCDIR([src/terminal.c])
11AC_CONFIG_HEADERS([config.h])
12
13AM_INIT_AUTOMAKE([1.9 foreign no-dist-gzip dist-bzip2])
14
15m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([no])])
16
17GETTEXT_PACKAGE=gnome-terminal
18AC_SUBST([GETTEXT_PACKAGE])
19AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],["$GETTEXT_PACKAGE"],[Gettext package])
20
21AC_C_BIGENDIAN
22
23if test -z "$enable_maintainer_mode"; then
24 enable_maintainer_mode=yes
25fi
26AM_MAINTAINER_MODE([enable])
27
28PKG_PROG_PKG_CONFIG
29AC_PROG_CC
30AC_ISC_POSIX
31AC_HEADER_STDC
32AM_PROG_LIBTOOL
33IT_PROG_INTLTOOL([0.40.0])
34
35GNOME_COMMON_INIT
36GNOME_DEBUG_CHECK
37GNOME_COMPILE_WARNINGS([maximum])
38#GNOME_MAINTAINER_MODE_DEFINES
39
40AM_GLIB_GNU_GETTEXT
41
42GLIB_REQUIRED=2.25.0
43GIO_REQUIRED=2.25.12
44GTK_REQUIRED=2.14.0
45GCONF_REQUIRED=2.31.3
46VTE_REQUIRED=0.25.91
47
48AC_MSG_CHECKING([which gtk+ version to compile against])
49AC_ARG_WITH([gtk],
50 [AS_HELP_STRING([--with-gtk=2.0|3.0],[which gtk+ version to compile against (default: 2.0)])],
51 [case "$with_gtk" in
52 2.0|3.0) ;;
53 *) AC_MSG_ERROR([invalid gtk version specified]) ;;
54 esac],
55 [with_gtk=2.0])
56AC_MSG_RESULT([$with_gtk])
57
58case "$with_gtk" in
59 2.0) GTK_API_VERSION=2.0
60 GTK_REQUIRED=2.18.0
61 VTE_PC_VERSION=
62 ;;
63 3.0) GTK_API_VERSION=3.0
64 GTK_REQUIRED=2.90.6
65 VTE_PC_VERSION=-2.90
66 ;;
67esac
68
69GDK_TARGET="$($PKG_CONFIG --variable target gdk-$GTK_API_VERSION)"
70
71case "$GDK_TARGET" in
72 x11) PLATFORM_DEPS="x11" ;;
73 *) PLATFORM_DEPS="" ;;
74esac
75
76PKG_CHECK_MODULES([TERM],
77 [vte$VTE_PC_VERSION >= $VTE_REQUIRED
78 glib-2.0 >= $GLIB_REQUIRED
79 gthread-2.0
80 gio-2.0 >= $GIO_REQUIRED
81 gtk+-$GTK_API_VERSION >= $GTK_REQUIRED
82 gconf-2.0 >= $GCONF_REQUIRED
83 $PLATFORM_DEPS])
84
85# ********
86# smclient
87# ********
88
89SMCLIENT_PKGS=
90AC_MSG_CHECKING([which smclient backend to use])
91AC_ARG_WITH([smclient],
92 [AS_HELP_STRING([--with-smclient-backend],[which smclient backend to use (xsmp/win32/quartz)])],
93 [],
94 [case "$GDK_TARGET" in
95 x11) with_smclient=xsmp SMCLIENT_PKGS="sm" ;;
96 win32|quartz) with_smclient=$GDK_TARGET ;;
97 *) with_smclient=no ;;
98 esac])
99AC_MSG_RESULT([$with_smclient])
100
101if test "$with_smclient" != "no"; then
102 AC_DEFINE([WITH_SMCLIENT],[1],[Define if smclient is enabled])
103fi
104
105if test -n "$SMCLIENT_PKGS"; then
106 PKG_CHECK_MODULES([SMCLIENT],[$SMCLIENT_PKGS])
107 AC_SUBST([SMCLIENT_CFLAGS])
108 AC_SUBST([SMCLIENT_LIBS])
109fi
110
111AM_CONDITIONAL([WITH_SMCLIENT],[test "$with_smclient" != "no"])
112AM_CONDITIONAL([WITH_SMCLIENT_XSMP],[test "$with_smclient" = "xsmp"])
113AM_CONDITIONAL([WITH_SMCLIENT_WIN32],[test "$with_smclient" = "win32"])
114AM_CONDITIONAL([WITH_SMCLIENT_QUARTZ],[test "$with_smclient" = "quartz"])
115
116# *****
117# GConf
118# *****
119
120AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
121
122if test x"$GCONFTOOL" = xno; then
123 AC_MSG_ERROR([gconftool-2 executable not found in your path - should be installed with GConf])
124fi
125
126AM_GCONF_SOURCE_2
127
128GLIB_GENMARSHAL="$($PKG_CONFIG --variable=glib_genmarshal glib-2.0)"
129AC_SUBST([GLIB_GENMARSHAL])
130GLIB_MKENUMS="$($PKG_CONFIG --variable=glib_mkenums glib-2.0)"
131AC_SUBST([GLIB_MKENUMS])
132
133AC_PATH_PROG([GTK_BUILDER_CONVERT],[gtk-builder-convert],[false])
134if test "$GTK_BUILDER_CONVERT" = "false"; then
135 AC_MSG_ERROR([gtk-builder-convert not found])
136fi
137
138# *****
139# S/Key
140# *****
141
142AC_MSG_CHECKING([whether to enable s/key support])
143AC_ARG_ENABLE([skey],
144 [AS_HELP_STRING([--disable-skey],[disable s/key support (default: enabled)])],
145 [],[enable_skey=yes])
146AC_MSG_RESULT([$enable_skey])
147
148if test "$enable_skey" = "yes"; then
149 AC_DEFINE([ENABLE_SKEY],[1],[Define if s/key support is enabled])
150fi
151
152AM_CONDITIONAL([ENABLE_SKEY],[test "$enable_skey" = "yes"])
153
154# *************
155# Documentation
156# *************
157
158GNOME_DOC_INIT
159
160# ****************************
161
162AC_SUBST([TERMINAL_MAJOR_VERSION],[gt_version_major])
163AC_SUBST([TERMINAL_MINOR_VERSION],[gt_version_minor])
164AC_SUBST([TERMINAL_MICRO_VERSION],[gt_version_micro])
165AC_SUBST([TERMINAL_API_VERSION],[gt_api_version])
166
167# ****************************
168
169AC_CONFIG_FILES([
170Makefile
171gnome-terminal.desktop.in
172src/Makefile
173src/terminal-version.h
174src/skey/Makefile
175help/Makefile
176help/bg/Makefile
177help/ro/Makefile
178help/ja/Makefile
179help/zh_TW/Makefile
180po/Makefile.in
181])
182AC_OUTPUT
183
184# ****************************
185
186echo "
187gnome-terminal-$VERSION:
188
189 prefix: ${prefix}
190 source code location: ${srcdir}
191 compiler: ${CC}
192
193 using smclient: ${with_smclient}
194 s/key support: ${enable_skey}
195"
0196
=== added directory '.pc/01_lpi.patch/src'
=== added file '.pc/01_lpi.patch/src/terminal-window.c'
--- .pc/01_lpi.patch/src/terminal-window.c 1970-01-01 00:00:00 +0000
+++ .pc/01_lpi.patch/src/terminal-window.c 2011-05-27 08:11:08 +0000
@@ -0,0 +1,4026 @@
1/*
2 * Copyright © 2001 Havoc Pennington
3 * Copyright © 2002 Red Hat, Inc.
4 * Copyright © 2007, 2008, 2009 Christian Persch
5 *
6 * Gnome-terminal is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Gnome-terminal is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <config.h>
21
22#include <string.h>
23#include <stdlib.h>
24#include <gtk/gtk.h>
25#ifdef GDK_WINDOWING_X11
26#include <gdk/gdkx.h>
27#endif
28#include <gdk/gdkkeysyms.h>
29
30#include "terminal-accels.h"
31#include "terminal-app.h"
32#include "terminal-debug.h"
33#include "terminal-encoding.h"
34#include "terminal-intl.h"
35#include "terminal-screen-container.h"
36#include "terminal-search-dialog.h"
37#include "terminal-tab-label.h"
38#include "terminal-tabs-menu.h"
39#include "terminal-util.h"
40#include "terminal-window.h"
41
42#ifdef ENABLE_SKEY
43#include "skey-popup.h"
44#endif
45
46struct _TerminalWindowPrivate
47{
48 GtkActionGroup *action_group;
49 GtkUIManager *ui_manager;
50 guint ui_id;
51
52 GtkActionGroup *profiles_action_group;
53 guint profiles_ui_id;
54
55 GtkActionGroup *encodings_action_group;
56 guint encodings_ui_id;
57
58 TerminalTabsMenu *tabs_menu;
59
60 TerminalScreenPopupInfo *popup_info;
61 guint remove_popup_info_idle;
62
63 GtkActionGroup *new_terminal_action_group;
64 guint new_terminal_ui_id;
65
66 GtkWidget *menubar;
67 GtkWidget *notebook;
68 TerminalScreen *active_screen;
69 int old_char_width;
70 int old_char_height;
71 void *old_geometry_widget; /* only used for pointer value as it may be freed */
72
73 GtkWidget *confirm_close_dialog;
74 GtkWidget *search_find_dialog;
75
76 guint menubar_visible : 1;
77 guint use_default_menubar_visibility : 1;
78
79 /* Compositing manager integration */
80 guint have_argb_visual : 1;
81
82 /* Used to clear stray "demands attention" flashing on our window when we
83 * unmap and map it to switch to an ARGB visual.
84 */
85 guint clear_demands_attention : 1;
86
87 guint disposed : 1;
88 guint present_on_insert : 1;
89
90 /* Workaround until gtk+ bug #535557 is fixed */
91 guint icon_title_set : 1;
92};
93
94#define PROFILE_DATA_KEY "GT::Profile"
95
96#define FILE_NEW_TERMINAL_TAB_UI_PATH "/menubar/File/FileNewTabProfiles"
97#define FILE_NEW_TERMINAL_WINDOW_UI_PATH "/menubar/File/FileNewWindowProfiles"
98#define SET_ENCODING_UI_PATH "/menubar/Terminal/TerminalSetEncoding/EncodingsPH"
99#define SET_ENCODING_ACTION_NAME_PREFIX "TerminalSetEncoding"
100
101#define PROFILES_UI_PATH "/menubar/Terminal/TerminalProfiles"
102#define PROFILES_POPUP_UI_PATH "/Popup/PopupTerminalProfiles/ProfilesPH"
103
104#define SIZE_TO_UI_PATH "/menubar/Terminal/TerminalSizeToPH"
105#define SIZE_TO_ACTION_NAME_PREFIX "TerminalSizeTo"
106
107#define STOCK_NEW_WINDOW "window-new"
108#define STOCK_NEW_TAB "tab-new"
109
110#define ENCODING_DATA_KEY "encoding"
111
112#if 1
113/*
114 * We don't want to enable content saving until vte supports it async.
115 * So we disable this code for stable versions.
116 */
117#include "terminal-version.h"
118
119#if (TERMINAL_MINOR_VERSION & 1) != 0
120#define ENABLE_SAVE
121#else
122#undef ENABLE_SAVE
123#endif
124#endif
125
126static void terminal_window_dispose (GObject *object);
127static void terminal_window_finalize (GObject *object);
128static gboolean terminal_window_state_event (GtkWidget *widget,
129 GdkEventWindowState *event);
130
131static gboolean terminal_window_delete_event (GtkWidget *widget,
132 GdkEvent *event,
133 gpointer data);
134
135static gboolean notebook_button_press_cb (GtkWidget *notebook,
136 GdkEventButton *event,
137 TerminalWindow *window);
138static gboolean notebook_popup_menu_cb (GtkWidget *notebook,
139 TerminalWindow *window);
140static void notebook_page_selected_callback (GtkWidget *notebook,
141#if GTK_CHECK_VERSION (2, 90, 6)
142 GtkWidget *page,
143#else
144 gpointer page,
145#endif
146 guint page_num,
147 TerminalWindow *window);
148static void notebook_page_added_callback (GtkWidget *notebook,
149 GtkWidget *container,
150 guint page_num,
151 TerminalWindow *window);
152static void notebook_page_removed_callback (GtkWidget *notebook,
153 GtkWidget *container,
154 guint page_num,
155 TerminalWindow *window);
156
157/* Menu action callbacks */
158static void file_new_window_callback (GtkAction *action,
159 TerminalWindow *window);
160static void file_new_tab_callback (GtkAction *action,
161 TerminalWindow *window);
162static void file_new_profile_callback (GtkAction *action,
163 TerminalWindow *window);
164static void file_close_window_callback (GtkAction *action,
165 TerminalWindow *window);
166static void file_save_contents_callback (GtkAction *action,
167 TerminalWindow *window);
168static void file_close_tab_callback (GtkAction *action,
169 TerminalWindow *window);
170static void edit_copy_callback (GtkAction *action,
171 TerminalWindow *window);
172static void edit_paste_callback (GtkAction *action,
173 TerminalWindow *window);
174static void edit_select_all_callback (GtkAction *action,
175 TerminalWindow *window);
176static void edit_keybindings_callback (GtkAction *action,
177 TerminalWindow *window);
178static void edit_profiles_callback (GtkAction *action,
179 TerminalWindow *window);
180static void edit_current_profile_callback (GtkAction *action,
181 TerminalWindow *window);
182static void view_menubar_toggled_callback (GtkToggleAction *action,
183 TerminalWindow *window);
184static void view_fullscreen_toggled_callback (GtkToggleAction *action,
185 TerminalWindow *window);
186static void view_zoom_in_callback (GtkAction *action,
187 TerminalWindow *window);
188static void view_zoom_out_callback (GtkAction *action,
189 TerminalWindow *window);
190static void view_zoom_normal_callback (GtkAction *action,
191 TerminalWindow *window);
192static void search_find_callback (GtkAction *action,
193 TerminalWindow *window);
194static void search_find_next_callback (GtkAction *action,
195 TerminalWindow *window);
196static void search_find_prev_callback (GtkAction *action,
197 TerminalWindow *window);
198static void search_clear_highlight_callback (GtkAction *action,
199 TerminalWindow *window);
200static void terminal_set_title_callback (GtkAction *action,
201 TerminalWindow *window);
202static void terminal_add_encoding_callback (GtkAction *action,
203 TerminalWindow *window);
204static void terminal_reset_callback (GtkAction *action,
205 TerminalWindow *window);
206static void terminal_reset_clear_callback (GtkAction *action,
207 TerminalWindow *window);
208static void tabs_next_or_previous_tab_cb (GtkAction *action,
209 TerminalWindow *window);
210static void tabs_move_left_callback (GtkAction *action,
211 TerminalWindow *window);
212static void tabs_move_right_callback (GtkAction *action,
213 TerminalWindow *window);
214static void tabs_detach_tab_callback (GtkAction *action,
215 TerminalWindow *window);
216static void help_contents_callback (GtkAction *action,
217 TerminalWindow *window);
218static void help_about_callback (GtkAction *action,
219 TerminalWindow *window);
220
221static gboolean find_larger_zoom_factor (double current,
222 double *found);
223static gboolean find_smaller_zoom_factor (double current,
224 double *found);
225
226static void terminal_window_show (GtkWidget *widget);
227
228static gboolean confirm_close_window_or_tab (TerminalWindow *window,
229 TerminalScreen *screen);
230
231static void
232profile_set_callback (TerminalScreen *screen,
233 TerminalProfile *old_profile,
234 TerminalWindow *window);
235static void
236sync_screen_icon_title (TerminalScreen *screen,
237 GParamSpec *psepc,
238 TerminalWindow *window);
239
240G_DEFINE_TYPE (TerminalWindow, terminal_window, GTK_TYPE_WINDOW)
241
242/* Menubar mnemonics & accel settings handling */
243
244static void
245app_setting_notify_cb (TerminalApp *app,
246 GParamSpec *pspec,
247 GdkScreen *screen)
248{
249 GtkSettings *settings;
250 const char *prop_name;
251
252 if (pspec)
253 prop_name = pspec->name;
254 else
255 prop_name = NULL;
256
257 settings = gtk_settings_get_for_screen (screen);
258
259 if (!prop_name || prop_name == I_(TERMINAL_APP_ENABLE_MNEMONICS))
260 {
261 gboolean enable_mnemonics;
262
263 g_object_get (app, TERMINAL_APP_ENABLE_MNEMONICS, &enable_mnemonics, NULL);
264 g_object_set (settings, "gtk-enable-mnemonics", enable_mnemonics, NULL);
265 }
266
267 if (!prop_name || prop_name == I_(TERMINAL_APP_ENABLE_MENU_BAR_ACCEL))
268 {
269 /* const */ char *saved_menubar_accel;
270 gboolean enable_menubar_accel;
271
272 /* FIXME: Once gtk+ bug 507398 is fixed, use that to reset the property instead */
273 /* Now this is a bad hack on so many levels. */
274 saved_menubar_accel = g_object_get_data (G_OBJECT (settings), "GT::gtk-menu-bar-accel");
275 if (!saved_menubar_accel)
276 {
277 g_object_get (settings, "gtk-menu-bar-accel", &saved_menubar_accel, NULL);
278 g_object_set_data_full (G_OBJECT (settings), "GT::gtk-menu-bar-accel",
279 saved_menubar_accel, (GDestroyNotify) g_free);
280 }
281
282 g_object_get (app, TERMINAL_APP_ENABLE_MENU_BAR_ACCEL, &enable_menubar_accel, NULL);
283 if (enable_menubar_accel)
284 g_object_set (settings, "gtk-menu-bar-accel", saved_menubar_accel, NULL);
285 else
286 g_object_set (settings, "gtk-menu-bar-accel", NULL, NULL);
287 }
288}
289
290static void
291app_setting_notify_destroy_cb (GdkScreen *screen)
292{
293 g_signal_handlers_disconnect_by_func (terminal_app_get (),
294 G_CALLBACK (app_setting_notify_cb),
295 screen);
296}
297
298/* utility functions */
299
300static char *
301escape_underscores (const char *name)
302{
303 GString *escaped_name;
304
305 g_assert (name != NULL);
306
307 /* Who'd use more that 4 underscores in a profile name... */
308 escaped_name = g_string_sized_new (strlen (name) + 4 + 1);
309
310 while (*name)
311 {
312 if (*name == '_')
313 g_string_append (escaped_name, "__");
314 else
315 g_string_append_c (escaped_name, *name);
316 name++;
317 }
318
319 return g_string_free (escaped_name, FALSE);
320}
321
322static int
323find_tab_num_at_pos (GtkNotebook *notebook,
324 int screen_x,
325 int screen_y)
326{
327 GtkPositionType tab_pos;
328 int page_num = 0;
329 GtkNotebook *nb = GTK_NOTEBOOK (notebook);
330 GtkWidget *page;
331 GtkAllocation tab_allocation;
332
333 tab_pos = gtk_notebook_get_tab_pos (GTK_NOTEBOOK (notebook));
334
335 while ((page = gtk_notebook_get_nth_page (nb, page_num)))
336 {
337 GtkWidget *tab;
338 int max_x, max_y, x_root, y_root;
339
340 tab = gtk_notebook_get_tab_label (nb, page);
341 g_return_val_if_fail (tab != NULL, -1);
342
343 if (!gtk_widget_get_mapped (GTK_WIDGET (tab)))
344 {
345 page_num++;
346 continue;
347 }
348
349 gdk_window_get_origin (gtk_widget_get_window (tab), &x_root, &y_root);
350
351 gtk_widget_get_allocation (tab, &tab_allocation);
352 max_x = x_root + tab_allocation.x + tab_allocation.width;
353 max_y = y_root + tab_allocation.y + tab_allocation.height;
354
355 if ((tab_pos == GTK_POS_TOP || tab_pos == GTK_POS_BOTTOM) && screen_x <= max_x)
356 return page_num;
357
358 if ((tab_pos == GTK_POS_LEFT || tab_pos == GTK_POS_RIGHT) && screen_y <= max_y)
359 return page_num;
360
361 page_num++;
362 }
363
364 return -1;
365}
366
367static void
368position_menu_under_widget (GtkMenu *menu,
369 int *x,
370 int *y,
371 gboolean *push_in,
372 gpointer user_data)
373{
374 /* Adapted from gtktoolbar.c */
375 GtkWidget *widget = GTK_WIDGET (user_data);
376 GdkWindow *widget_window;
377 GtkWidget *container;
378 GtkRequisition req;
379 GtkRequisition menu_req;
380 GdkRectangle monitor;
381 int monitor_num;
382 GdkScreen *screen;
383 GtkAllocation widget_allocation;
384
385 widget_window = gtk_widget_get_window (widget);
386 gtk_widget_get_allocation (widget, &widget_allocation);
387 container = gtk_widget_get_ancestor (widget, GTK_TYPE_CONTAINER);
388
389 gtk_widget_size_request (widget, &req);
390 gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
391
392 screen = gtk_widget_get_screen (GTK_WIDGET (menu));
393 monitor_num = gdk_screen_get_monitor_at_window (screen, widget_window);
394 if (monitor_num < 0)
395 monitor_num = 0;
396 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
397
398 gdk_window_get_origin (widget_window, x, y);
399 if (!gtk_widget_get_has_window (widget))
400 {
401 *x += widget_allocation.x;
402 *y += widget_allocation.y;
403 }
404 if (gtk_widget_get_direction (container) == GTK_TEXT_DIR_LTR)
405 *x += widget_allocation.width - req.width;
406 else
407 *x += req.width - menu_req.width;
408
409 if ((*y + widget_allocation.height + menu_req.height) <= monitor.y + monitor.height)
410 *y += widget_allocation.height;
411 else if ((*y - menu_req.height) >= monitor.y)
412 *y -= menu_req.height;
413 else if (monitor.y + monitor.height - (*y + widget_allocation.height) > *y)
414 *y += widget_allocation.height;
415 else
416 *y -= menu_req.height;
417
418 *push_in = FALSE;
419}
420
421static void
422terminal_set_profile_toggled_callback (GtkToggleAction *action,
423 TerminalWindow *window)
424{
425 TerminalWindowPrivate *priv = window->priv;
426 TerminalProfile *profile;
427
428 if (!gtk_toggle_action_get_active (action))
429 return;
430
431 if (priv->active_screen == NULL)
432 return;
433
434 profile = g_object_get_data (G_OBJECT (action), PROFILE_DATA_KEY);
435 g_assert (profile);
436
437 if (_terminal_profile_get_forgotten (profile))
438 return;
439
440 g_signal_handlers_block_by_func (priv->active_screen, G_CALLBACK (profile_set_callback), window);
441 terminal_screen_set_profile (priv->active_screen, profile);
442 g_signal_handlers_unblock_by_func (priv->active_screen, G_CALLBACK (profile_set_callback), window);
443}
444
445static void
446profile_visible_name_notify_cb (TerminalProfile *profile,
447 GParamSpec *pspec,
448 GtkAction *action)
449{
450 const char *visible_name;
451 char *dot, *display_name;
452 guint num;
453
454 visible_name = terminal_profile_get_property_string (profile, TERMINAL_PROFILE_VISIBLE_NAME);
455 display_name = escape_underscores (visible_name);
456
457 dot = strchr (gtk_action_get_name (action), '.');
458 if (dot != NULL)
459 {
460 char *free_me;
461
462 num = g_ascii_strtoll (dot + 1, NULL, 10);
463
464 free_me = display_name;
465 if (num < 10)
466 /* Translators: This is the label of a menu item to choose a profile.
467 * _%d is used as the accelerator (with d between 1 and 9), and
468 * the %s is the name of the terminal profile.
469 */
470 display_name = g_strdup_printf (_("_%d. %s"), num, display_name);
471 else if (num < 36)
472 /* Translators: This is the label of a menu item to choose a profile.
473 * _%c is used as the accelerator (it will be a character between A and Z),
474 * and the %s is the name of the terminal profile.
475 */
476 display_name = g_strdup_printf (_("_%c. %s"), ('A' + num - 10), display_name);
477 else
478 free_me = NULL;
479
480 g_free (free_me);
481 }
482
483 g_object_set (action, "label", display_name, NULL);
484 g_free (display_name);
485}
486
487static void
488disconnect_profiles_from_actions_in_group (GtkActionGroup *action_group)
489{
490 GList *actions, *l;
491
492 actions = gtk_action_group_list_actions (action_group);
493 for (l = actions; l != NULL; l = l->next)
494 {
495 GObject *action = G_OBJECT (l->data);
496 TerminalProfile *profile;
497
498 profile = g_object_get_data (action, PROFILE_DATA_KEY);
499 if (!profile)
500 continue;
501
502 g_signal_handlers_disconnect_by_func (profile, G_CALLBACK (profile_visible_name_notify_cb), action);
503 }
504 g_list_free (actions);
505}
506
507static void
508terminal_window_update_set_profile_menu_active_profile (TerminalWindow *window)
509{
510 TerminalWindowPrivate *priv = window->priv;
511 TerminalProfile *new_active_profile;
512 GList *actions, *l;
513
514 if (!priv->profiles_action_group)
515 return;
516
517 if (!priv->active_screen)
518 return;
519
520 new_active_profile = terminal_screen_get_profile (priv->active_screen);
521
522 actions = gtk_action_group_list_actions (priv->profiles_action_group);
523 for (l = actions; l != NULL; l = l->next)
524 {
525 GObject *action = G_OBJECT (l->data);
526 TerminalProfile *profile;
527
528 profile = g_object_get_data (action, PROFILE_DATA_KEY);
529 if (profile != new_active_profile)
530 continue;
531
532 g_signal_handlers_block_by_func (action, G_CALLBACK (terminal_set_profile_toggled_callback), window);
533 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
534 g_signal_handlers_unblock_by_func (action, G_CALLBACK (terminal_set_profile_toggled_callback), window);
535
536 break;
537 }
538 g_list_free (actions);
539}
540
541static void
542terminal_window_update_set_profile_menu (TerminalWindow *window)
543{
544 TerminalWindowPrivate *priv = window->priv;
545 TerminalProfile *active_profile;
546 GtkActionGroup *action_group;
547 GtkAction *action;
548 GList *profiles, *p;
549 GSList *group;
550 guint n;
551 gboolean single_profile;
552
553 /* Remove the old UI */
554 if (priv->profiles_ui_id != 0)
555 {
556 gtk_ui_manager_remove_ui (priv->ui_manager, priv->profiles_ui_id);
557 priv->profiles_ui_id = 0;
558 }
559
560 if (priv->profiles_action_group != NULL)
561 {
562 disconnect_profiles_from_actions_in_group (priv->profiles_action_group);
563 gtk_ui_manager_remove_action_group (priv->ui_manager,
564 priv->profiles_action_group);
565 priv->profiles_action_group = NULL;
566 }
567
568 profiles = terminal_app_get_profile_list (terminal_app_get ());
569
570 action = gtk_action_group_get_action (priv->action_group, "TerminalProfiles");
571 single_profile = !profiles || profiles->next == NULL; /* list length <= 1 */
572 gtk_action_set_sensitive (action, !single_profile);
573 if (profiles == NULL)
574 return;
575
576 if (priv->active_screen)
577 active_profile = terminal_screen_get_profile (priv->active_screen);
578 else
579 active_profile = NULL;
580
581 action_group = priv->profiles_action_group = gtk_action_group_new ("Profiles");
582 gtk_ui_manager_insert_action_group (priv->ui_manager, action_group, -1);
583 g_object_unref (action_group);
584
585 priv->profiles_ui_id = gtk_ui_manager_new_merge_id (priv->ui_manager);
586
587 group = NULL;
588 n = 0;
589 for (p = profiles; p != NULL; p = p->next)
590 {
591 TerminalProfile *profile = (TerminalProfile *) p->data;
592 GtkRadioAction *profile_action;
593 char name[32];
594
595 g_snprintf (name, sizeof (name), "TerminalSetProfile%u", n++);
596
597 profile_action = gtk_radio_action_new (name,
598 NULL,
599 NULL,
600 NULL,
601 n);
602
603 gtk_radio_action_set_group (profile_action, group);
604 group = gtk_radio_action_get_group (profile_action);
605
606 if (profile == active_profile)
607 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (profile_action), TRUE);
608
609 g_object_set_data_full (G_OBJECT (profile_action),
610 PROFILE_DATA_KEY,
611 g_object_ref (profile),
612 (GDestroyNotify) g_object_unref);
613 profile_visible_name_notify_cb (profile, NULL, GTK_ACTION (profile_action));
614 g_signal_connect (profile, "notify::" TERMINAL_PROFILE_VISIBLE_NAME,
615 G_CALLBACK (profile_visible_name_notify_cb), profile_action);
616 g_signal_connect (profile_action, "toggled",
617 G_CALLBACK (terminal_set_profile_toggled_callback), window);
618
619 gtk_action_group_add_action (action_group, GTK_ACTION (profile_action));
620 g_object_unref (profile_action);
621
622 gtk_ui_manager_add_ui (priv->ui_manager, priv->profiles_ui_id,
623 PROFILES_UI_PATH,
624 name, name,
625 GTK_UI_MANAGER_MENUITEM, FALSE);
626 gtk_ui_manager_add_ui (priv->ui_manager, priv->profiles_ui_id,
627 PROFILES_POPUP_UI_PATH,
628 name, name,
629 GTK_UI_MANAGER_MENUITEM, FALSE);
630 }
631
632 g_list_free (profiles);
633}
634
635static void
636terminal_window_create_new_terminal_action (TerminalWindow *window,
637 TerminalProfile *profile,
638 const char *name,
639 guint num,
640 GCallback callback)
641{
642 TerminalWindowPrivate *priv = window->priv;
643 GtkAction *action;
644
645 action = gtk_action_new (name, NULL, NULL, NULL);
646
647 g_object_set_data_full (G_OBJECT (action),
648 PROFILE_DATA_KEY,
649 g_object_ref (profile),
650 (GDestroyNotify) g_object_unref);
651 profile_visible_name_notify_cb (profile, NULL, action);
652 g_signal_connect (profile, "notify::" TERMINAL_PROFILE_VISIBLE_NAME,
653 G_CALLBACK (profile_visible_name_notify_cb), action);
654 g_signal_connect (action, "activate", callback, window);
655
656 gtk_action_group_add_action (priv->new_terminal_action_group, action);
657 g_object_unref (action);
658}
659
660static void
661terminal_window_update_new_terminal_menus (TerminalWindow *window)
662{
663 TerminalWindowPrivate *priv = window->priv;
664 GtkActionGroup *action_group;
665 GtkAction *action;
666 GList *profiles, *p;
667 guint n;
668 gboolean have_single_profile;
669
670 /* Remove the old UI */
671 if (priv->new_terminal_ui_id != 0)
672 {
673 gtk_ui_manager_remove_ui (priv->ui_manager, priv->new_terminal_ui_id);
674 priv->new_terminal_ui_id = 0;
675 }
676
677 if (priv->new_terminal_action_group != NULL)
678 {
679 disconnect_profiles_from_actions_in_group (priv->new_terminal_action_group);
680 gtk_ui_manager_remove_action_group (priv->ui_manager,
681 priv->new_terminal_action_group);
682 priv->new_terminal_action_group = NULL;
683 }
684
685 profiles = terminal_app_get_profile_list (terminal_app_get ());
686 have_single_profile = !profiles || !profiles->next;
687
688 action = gtk_action_group_get_action (priv->action_group, "FileNewTab");
689 gtk_action_set_visible (action, have_single_profile);
690 action = gtk_action_group_get_action (priv->action_group, "FileNewWindow");
691 gtk_action_set_visible (action, have_single_profile);
692
693 if (have_single_profile)
694 {
695 g_list_free (profiles);
696 return;
697 }
698
699 /* Now build the submenus */
700
701 action_group = priv->new_terminal_action_group = gtk_action_group_new ("NewTerminal");
702 gtk_ui_manager_insert_action_group (priv->ui_manager, action_group, -1);
703 g_object_unref (action_group);
704
705 priv->new_terminal_ui_id = gtk_ui_manager_new_merge_id (priv->ui_manager);
706
707 n = 0;
708 for (p = profiles; p != NULL; p = p->next)
709 {
710 TerminalProfile *profile = (TerminalProfile *) p->data;
711 char name[32];
712
713 g_snprintf (name, sizeof (name), "FileNewTab.%u", n);
714 terminal_window_create_new_terminal_action (window,
715 profile,
716 name,
717 n,
718 G_CALLBACK (file_new_tab_callback));
719
720 gtk_ui_manager_add_ui (priv->ui_manager, priv->new_terminal_ui_id,
721 FILE_NEW_TERMINAL_TAB_UI_PATH,
722 name, name,
723 GTK_UI_MANAGER_MENUITEM, FALSE);
724
725 g_snprintf (name, sizeof (name), "FileNewWindow.%u", n);
726 terminal_window_create_new_terminal_action (window,
727 profile,
728 name,
729 n,
730 G_CALLBACK (file_new_window_callback));
731
732 gtk_ui_manager_add_ui (priv->ui_manager, priv->new_terminal_ui_id,
733 FILE_NEW_TERMINAL_WINDOW_UI_PATH,
734 name, name,
735 GTK_UI_MANAGER_MENUITEM, FALSE);
736
737 ++n;
738 }
739
740 g_list_free (profiles);
741}
742
743static void
744terminal_set_encoding_callback (GtkToggleAction *action,
745 TerminalWindow *window)
746{
747 TerminalWindowPrivate *priv = window->priv;
748 TerminalEncoding *encoding;
749
750 if (!gtk_toggle_action_get_active (action))
751 return;
752
753 if (priv->active_screen == NULL)
754 return;
755
756 encoding = g_object_get_data (G_OBJECT (action), ENCODING_DATA_KEY);
757 g_assert (encoding);
758
759 vte_terminal_set_encoding (VTE_TERMINAL (priv->active_screen),
760 terminal_encoding_get_charset (encoding));
761}
762
763static void
764terminal_window_update_encoding_menu (TerminalWindow *window)
765{
766 TerminalWindowPrivate *priv = window->priv;
767 TerminalApp *app;
768 GtkActionGroup *action_group;
769 GSList *group;
770 guint n;
771 GSList *encodings, *l;
772 const char *charset;
773 TerminalEncoding *active_encoding;
774
775 /* Remove the old UI */
776 if (priv->encodings_ui_id != 0)
777 {
778 gtk_ui_manager_remove_ui (priv->ui_manager, priv->encodings_ui_id);
779 priv->encodings_ui_id = 0;
780 }
781
782 if (priv->encodings_action_group != NULL)
783 {
784 gtk_ui_manager_remove_action_group (priv->ui_manager,
785 priv->encodings_action_group);
786 priv->encodings_action_group = NULL;
787 }
788
789 action_group = priv->encodings_action_group = gtk_action_group_new ("Encodings");
790 gtk_ui_manager_insert_action_group (priv->ui_manager, action_group, -1);
791 g_object_unref (action_group);
792
793 priv->encodings_ui_id = gtk_ui_manager_new_merge_id (priv->ui_manager);
794
795 if (priv->active_screen)
796 charset = vte_terminal_get_encoding (VTE_TERMINAL (priv->active_screen));
797 else
798 charset = "current";
799
800 app = terminal_app_get ();
801 active_encoding = terminal_app_ensure_encoding (app, charset);
802
803 encodings = terminal_app_get_active_encodings (app);
804
805 if (g_slist_find (encodings, active_encoding) == NULL)
806 encodings = g_slist_append (encodings, terminal_encoding_ref (active_encoding));
807
808 group = NULL;
809 n = 0;
810 for (l = encodings; l != NULL; l = l->next)
811 {
812 TerminalEncoding *e = (TerminalEncoding *) l->data;
813 GtkRadioAction *encoding_action;
814 char name[128];
815 char *display_name;
816
817 g_snprintf (name, sizeof (name), SET_ENCODING_ACTION_NAME_PREFIX "%s", terminal_encoding_get_id (e));
818 display_name = g_strdup_printf ("%s (%s)", e->name, terminal_encoding_get_charset (e));
819
820 encoding_action = gtk_radio_action_new (name,
821 display_name,
822 NULL,
823 NULL,
824 n);
825 g_free (display_name);
826
827 gtk_radio_action_set_group (encoding_action, group);
828 group = gtk_radio_action_get_group (encoding_action);
829
830 if (charset && strcmp (terminal_encoding_get_id (e), charset) == 0)
831 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (encoding_action), TRUE);
832
833 g_signal_connect (encoding_action, "toggled",
834 G_CALLBACK (terminal_set_encoding_callback), window);
835
836 g_object_set_data_full (G_OBJECT (encoding_action), ENCODING_DATA_KEY,
837 terminal_encoding_ref (e),
838 (GDestroyNotify) terminal_encoding_unref);
839
840 gtk_action_group_add_action (action_group, GTK_ACTION (encoding_action));
841 g_object_unref (encoding_action);
842
843 gtk_ui_manager_add_ui (priv->ui_manager, priv->encodings_ui_id,
844 SET_ENCODING_UI_PATH,
845 name, name,
846 GTK_UI_MANAGER_MENUITEM, FALSE);
847 }
848
849 g_slist_foreach (encodings, (GFunc) terminal_encoding_unref, NULL);
850 g_slist_free (encodings);
851}
852
853static void
854terminal_window_update_encoding_menu_active_encoding (TerminalWindow *window)
855{
856 TerminalWindowPrivate *priv = window->priv;
857 GtkAction *action;
858 char name[128];
859
860 if (!priv->active_screen)
861 return;
862 if (!priv->encodings_action_group)
863 return;
864
865 g_snprintf (name, sizeof (name), SET_ENCODING_ACTION_NAME_PREFIX "%s",
866 vte_terminal_get_encoding (VTE_TERMINAL (priv->active_screen)));
867 action = gtk_action_group_get_action (priv->encodings_action_group, name);
868 if (!action)
869 return;
870
871 g_signal_handlers_block_by_func (action, G_CALLBACK (terminal_set_encoding_callback), window);
872 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
873 g_signal_handlers_unblock_by_func (action, G_CALLBACK (terminal_set_encoding_callback), window);
874}
875
876static void
877terminal_size_to_cb (GtkAction *action,
878 TerminalWindow *window)
879{
880 TerminalWindowPrivate *priv = window->priv;
881 const char *name;
882 char *end = NULL;
883 guint width, height;
884
885 if (priv->active_screen == NULL)
886 return;
887
888 name = gtk_action_get_name (action) + strlen (SIZE_TO_ACTION_NAME_PREFIX);
889 width = g_ascii_strtoull (name, &end, 10);
890 g_assert (end && *end == 'x');
891 height = g_ascii_strtoull (end + 1, &end, 10);
892 g_assert (end && *end == '\0');
893
894 vte_terminal_set_size (VTE_TERMINAL (priv->active_screen), width, height);
895
896 terminal_window_set_size_force_grid (window, priv->active_screen, TRUE, -1, -1);
897}
898
899static void
900terminal_window_update_size_to_menu (TerminalWindow *window)
901{
902 static const struct {
903 guint grid_width;
904 guint grid_height;
905 } predefined_sizes[] = {
906 { 80, 24 },
907 { 80, 43 },
908 { 132, 24 },
909 { 132, 43 }
910 };
911 TerminalWindowPrivate *priv = window->priv;
912 guint i;
913
914 /* We only install this once, so there's no need for a separate action group
915 * and any cleanup + build-new-one action here.
916 */
917
918 for (i = 0; i < G_N_ELEMENTS (predefined_sizes); ++i)
919 {
920 guint grid_width = predefined_sizes[i].grid_width;
921 guint grid_height = predefined_sizes[i].grid_height;
922 GtkAction *action;
923 char name[40];
924 char *display_name;
925
926 g_snprintf (name, sizeof (name), SIZE_TO_ACTION_NAME_PREFIX "%ux%u",
927 grid_width, grid_height);
928
929 /* If there are ever more than 9 of these, extend this to use A..Z as mnemonics,
930 * like we do for the profiles menu.
931 */
932 display_name = g_strdup_printf ("_%u. %ux%u", i + 1, grid_width, grid_height);
933
934 action = gtk_action_new (name, display_name, NULL, NULL);
935 g_free (display_name);
936
937 g_signal_connect (action, "activate",
938 G_CALLBACK (terminal_size_to_cb), window);
939
940 gtk_action_group_add_action (priv->action_group, action);
941 g_object_unref (action);
942
943 gtk_ui_manager_add_ui (priv->ui_manager, priv->ui_id,
944 SIZE_TO_UI_PATH,
945 name, name,
946 GTK_UI_MANAGER_MENUITEM, FALSE);
947 }
948}
949
950/* Actions stuff */
951
952static void
953terminal_window_update_copy_sensitivity (TerminalScreen *screen,
954 TerminalWindow *window)
955{
956 TerminalWindowPrivate *priv = window->priv;
957 GtkAction *action;
958 gboolean can_copy;
959
960 if (screen != priv->active_screen)
961 return;
962
963 can_copy = vte_terminal_get_has_selection (VTE_TERMINAL (screen));
964
965 action = gtk_action_group_get_action (priv->action_group, "EditCopy");
966 gtk_action_set_sensitive (action, can_copy);
967}
968
969static void
970terminal_window_update_zoom_sensitivity (TerminalWindow *window)
971{
972 TerminalWindowPrivate *priv = window->priv;
973 TerminalScreen *screen;
974 GtkAction *action;
975 double current, zoom;
976
977 screen = priv->active_screen;
978 if (screen == NULL)
979 return;
980
981 current = terminal_screen_get_font_scale (screen);
982
983 action = gtk_action_group_get_action (priv->action_group, "ViewZoomOut");
984 gtk_action_set_sensitive (action, find_smaller_zoom_factor (current, &zoom));
985 action = gtk_action_group_get_action (priv->action_group, "ViewZoomIn");
986 gtk_action_set_sensitive (action, find_larger_zoom_factor (current, &zoom));
987}
988
989static void
990terminal_window_update_search_sensitivity (TerminalScreen *screen,
991 TerminalWindow *window)
992{
993 TerminalWindowPrivate *priv = window->priv;
994 GtkAction *action;
995 gboolean can_search;
996
997 if (screen != priv->active_screen)
998 return;
999
1000 can_search = vte_terminal_search_get_gregex (VTE_TERMINAL (screen)) != NULL;
1001
1002 action = gtk_action_group_get_action (priv->action_group, "SearchFindNext");
1003 gtk_action_set_sensitive (action, can_search);
1004 action = gtk_action_group_get_action (priv->action_group, "SearchFindPrevious");
1005 gtk_action_set_sensitive (action, can_search);
1006 action = gtk_action_group_get_action (priv->action_group, "SearchClearHighlight");
1007 gtk_action_set_sensitive (action, can_search);
1008}
1009
1010static void
1011update_edit_menu_cb (GtkClipboard *clipboard,
1012 GdkAtom *targets,
1013 int n_targets,
1014 TerminalWindow *window)
1015{
1016 TerminalWindowPrivate *priv = window->priv;
1017 GtkAction *action;
1018 gboolean can_paste, can_paste_uris;
1019
1020 can_paste = targets != NULL && gtk_targets_include_text (targets, n_targets);
1021 can_paste_uris = targets != NULL && gtk_targets_include_uri (targets, n_targets);
1022
1023 action = gtk_action_group_get_action (priv->action_group, "EditPaste");
1024 gtk_action_set_sensitive (action, can_paste);
1025 action = gtk_action_group_get_action (priv->action_group, "EditPasteURIPaths");
1026 gtk_action_set_visible (action, can_paste_uris);
1027 gtk_action_set_sensitive (action, can_paste_uris);
1028
1029 /* Ref was added in gtk_clipboard_request_targets below */
1030 g_object_unref (window);
1031}
1032
1033static void
1034edit_menu_activate_callback (GtkMenuItem *menuitem,
1035 gpointer user_data)
1036{
1037 TerminalWindow *window = (TerminalWindow *) user_data;
1038 GtkClipboard *clipboard;
1039
1040 clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), GDK_SELECTION_CLIPBOARD);
1041 gtk_clipboard_request_targets (clipboard,
1042 (GtkClipboardTargetsReceivedFunc) update_edit_menu_cb,
1043 g_object_ref (window));
1044}
1045
1046static void
1047screen_resize_window_cb (TerminalScreen *screen,
1048 guint width,
1049 guint height,
1050 TerminalWindow* window)
1051{
1052 TerminalWindowPrivate *priv = window->priv;
1053 VteTerminal *terminal = VTE_TERMINAL (screen);
1054 GtkWidget *widget = GTK_WIDGET (screen);
1055 guint grid_width, grid_height;
1056 int char_width, char_height;
1057 GtkBorder *inner_border = NULL;
1058 GtkAllocation widget_allocation;
1059
1060 gtk_widget_get_allocation (widget, &widget_allocation);
1061 /* Don't do anything if we're maximised or fullscreened */
1062 // FIXME: realized && ... instead?
1063 if (!gtk_widget_get_realized (widget) ||
1064 (gdk_window_get_state (gtk_widget_get_window (widget)) & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) != 0)
1065 return;
1066
1067 /* NOTE: width and height already include the VteTerminal's padding! */
1068
1069 /* Short-circuit */
1070 if (((int) width) == widget_allocation.width &&
1071 ((int) height) == widget_allocation.height)
1072 return;
1073
1074 /* The resize-window signal sucks. Re-compute grid widths */
1075
1076 char_width = vte_terminal_get_char_width (terminal);
1077 char_height = vte_terminal_get_char_height (terminal);
1078
1079 gtk_widget_style_get (GTK_WIDGET (terminal), "inner-border", &inner_border, NULL);
1080 grid_width = (width - (inner_border ? (inner_border->left + inner_border->right) : 0)) / char_width;
1081 grid_height = (height - (inner_border ? (inner_border->top + inner_border->bottom) : 0)) / char_height;
1082 gtk_border_free (inner_border);
1083
1084 vte_terminal_set_size (terminal, grid_width, grid_height);
1085
1086 if (screen != priv->active_screen)
1087 return;
1088
1089 terminal_window_set_size_force_grid (window, screen, TRUE, -1, -1); //grid_width, grid_height);
1090}
1091
1092static void
1093terminal_window_update_tabs_menu_sensitivity (TerminalWindow *window)
1094{
1095 TerminalWindowPrivate *priv = window->priv;
1096 GtkNotebook *notebook = GTK_NOTEBOOK (priv->notebook);
1097 GtkActionGroup *action_group = priv->action_group;
1098 GtkAction *action;
1099 int num_pages, page_num;
1100 gboolean not_first, not_last;
1101
1102 if (priv->disposed)
1103 return;
1104
1105 num_pages = gtk_notebook_get_n_pages (notebook);
1106 page_num = gtk_notebook_get_current_page (notebook);
1107 not_first = page_num > 0;
1108 not_last = page_num + 1 < num_pages;
1109
1110 /* Hide the tabs menu in single-tab windows */
1111 action = gtk_action_group_get_action (action_group, "Tabs");
1112 gtk_action_set_visible (action, num_pages > 1);
1113
1114#if 1
1115 /* NOTE: We always make next/prev actions sensitive except in
1116 * single-tab windows, so the corresponding shortcut key escape code
1117 * isn't sent to the terminal. See bug #453193 and bug #138609.
1118 * This also makes tab cycling work, bug #92139.
1119 * FIXME: Find a better way to do this.
1120 */
1121 action = gtk_action_group_get_action (action_group, "TabsPrevious");
1122 gtk_action_set_sensitive (action, num_pages > 1);
1123 action = gtk_action_group_get_action (action_group, "TabsNext");
1124 gtk_action_set_sensitive (action, num_pages > 1);
1125#else
1126 /* This would be correct, but see the comment above. */
1127 action = gtk_action_group_get_action (action_group, "TabsPrevious");
1128 gtk_action_set_sensitive (action, not_first);
1129 action = gtk_action_group_get_action (action_group, "TabsNext");
1130 gtk_action_set_sensitive (action, not_last);
1131#endif
1132
1133 action = gtk_action_group_get_action (action_group, "TabsMoveLeft");
1134 gtk_action_set_sensitive (action, not_first);
1135 action = gtk_action_group_get_action (action_group, "TabsMoveRight");
1136 gtk_action_set_sensitive (action, not_last);
1137 action = gtk_action_group_get_action (action_group, "TabsDetach");
1138 gtk_action_set_sensitive (action, num_pages > 1);
1139 action = gtk_action_group_get_action (action_group, "FileCloseTab");
1140 gtk_action_set_sensitive (action, num_pages > 1);
1141}
1142
1143gboolean
1144terminal_window_uses_argb_visual (TerminalWindow *window)
1145{
1146 TerminalWindowPrivate *priv = window->priv;
1147 return priv->have_argb_visual;
1148}
1149
1150static void
1151update_tab_visibility (TerminalWindow *window,
1152 int change)
1153{
1154 TerminalWindowPrivate *priv = window->priv;
1155 gboolean show_tabs;
1156 guint num;
1157
1158 num = gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
1159
1160 show_tabs = (num + change) > 1;
1161 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), show_tabs);
1162}
1163
1164static GtkNotebook *
1165handle_tab_droped_on_desktop (GtkNotebook *source_notebook,
1166 GtkWidget *container,
1167 gint x,
1168 gint y,
1169 gpointer data)
1170{
1171 TerminalScreen *screen;
1172 TerminalWindow *source_window;
1173 TerminalWindow *new_window;
1174 TerminalWindowPrivate *new_priv;
1175
1176 screen = terminal_screen_container_get_screen (TERMINAL_SCREEN_CONTAINER (container));
1177 source_window = TERMINAL_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (source_notebook)));
1178 g_return_val_if_fail (TERMINAL_IS_WINDOW (source_window), NULL);
1179
1180 new_window = terminal_app_new_window (terminal_app_get (),
1181 gtk_widget_get_screen (GTK_WIDGET (source_window)));
1182 new_priv = new_window->priv;
1183 new_priv->present_on_insert = TRUE;
1184
1185 update_tab_visibility (source_window, -1);
1186 update_tab_visibility (new_window, +1);
1187
1188 return GTK_NOTEBOOK (new_priv->notebook);
1189}
1190
1191/* Terminal screen popup menu handling */
1192
1193static void
1194popup_open_url_callback (GtkAction *action,
1195 TerminalWindow *window)
1196{
1197 TerminalWindowPrivate *priv = window->priv;
1198 TerminalScreenPopupInfo *info = priv->popup_info;
1199
1200 if (info == NULL)
1201 return;
1202
1203 terminal_util_open_url (GTK_WIDGET (window), info->string, info->flavour,
1204 gtk_get_current_event_time ());
1205}
1206
1207static void
1208popup_copy_url_callback (GtkAction *action,
1209 TerminalWindow *window)
1210{
1211 TerminalWindowPrivate *priv = window->priv;
1212 TerminalScreenPopupInfo *info = priv->popup_info;
1213 GtkClipboard *clipboard;
1214
1215 if (info == NULL)
1216 return;
1217
1218 if (info->string == NULL)
1219 return;
1220
1221 clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), GDK_SELECTION_CLIPBOARD);
1222 gtk_clipboard_set_text (clipboard, info->string, -1);
1223}
1224
1225static void
1226popup_leave_fullscreen_callback (GtkAction *action,
1227 TerminalWindow *window)
1228{
1229 gtk_window_unfullscreen (GTK_WINDOW (window));
1230}
1231
1232static void
1233remove_popup_info (TerminalWindow *window)
1234{
1235 TerminalWindowPrivate *priv = window->priv;
1236
1237 if (priv->remove_popup_info_idle != 0)
1238 {
1239 g_source_remove (priv->remove_popup_info_idle);
1240 priv->remove_popup_info_idle = 0;
1241 }
1242
1243 if (priv->popup_info != NULL)
1244 {
1245 terminal_screen_popup_info_unref (priv->popup_info);
1246 priv->popup_info = NULL;
1247 }
1248}
1249
1250static gboolean
1251idle_remove_popup_info (TerminalWindow *window)
1252{
1253 TerminalWindowPrivate *priv = window->priv;
1254
1255 priv->remove_popup_info_idle = 0;
1256 remove_popup_info (window);
1257 return FALSE;
1258}
1259
1260static void
1261unset_popup_info (TerminalWindow *window)
1262{
1263 TerminalWindowPrivate *priv = window->priv;
1264
1265 /* Unref the event from idle since we still need it
1266 * from the action callbacks which will run before idle.
1267 */
1268 if (priv->remove_popup_info_idle == 0 &&
1269 priv->popup_info != NULL)
1270 {
1271 priv->remove_popup_info_idle =
1272 g_idle_add ((GSourceFunc) idle_remove_popup_info, window);
1273 }
1274}
1275
1276static void
1277popup_menu_deactivate_callback (GtkWidget *popup,
1278 TerminalWindow *window)
1279{
1280 TerminalWindowPrivate *priv = window->priv;
1281 GtkWidget *im_menu_item;
1282
1283 g_signal_handlers_disconnect_by_func
1284 (popup, G_CALLBACK (popup_menu_deactivate_callback), window);
1285
1286 im_menu_item = gtk_ui_manager_get_widget (priv->ui_manager,
1287 "/Popup/PopupInputMethods");
1288 gtk_menu_item_set_submenu (GTK_MENU_ITEM (im_menu_item), NULL);
1289
1290 unset_popup_info (window);
1291}
1292
1293static void
1294popup_clipboard_targets_received_cb (GtkClipboard *clipboard,
1295 GdkAtom *targets,
1296 int n_targets,
1297 TerminalScreenPopupInfo *info)
1298{
1299 TerminalWindow *window = info->window;
1300 TerminalWindowPrivate *priv = window->priv;
1301 TerminalScreen *screen = info->screen;
1302 GtkWidget *popup_menu, *im_menu, *im_menu_item;
1303 GtkAction *action;
1304 gboolean can_paste, can_paste_uris, show_link, show_email_link, show_call_link, show_input_method_menu;
1305 int n_pages;
1306
1307 if (!gtk_widget_get_realized (GTK_WIDGET (screen)))
1308 {
1309 terminal_screen_popup_info_unref (info);
1310 return;
1311 }
1312
1313 /* Now we know that the screen is realized, we know that the window is still alive */
1314 remove_popup_info (window);
1315
1316 priv->popup_info = info; /* adopt the ref added when requesting the clipboard */
1317
1318 n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
1319
1320 can_paste = targets != NULL && gtk_targets_include_text (targets, n_targets);
1321 can_paste_uris = targets != NULL && gtk_targets_include_uri (targets, n_targets);
1322 show_link = info->string != NULL && (info->flavour == FLAVOR_AS_IS || info->flavour == FLAVOR_DEFAULT_TO_HTTP);
1323 show_email_link = info->string != NULL && info->flavour == FLAVOR_EMAIL;
1324 show_call_link = info->string != NULL && info->flavour == FLAVOR_VOIP_CALL;
1325
1326 action = gtk_action_group_get_action (priv->action_group, "PopupSendEmail");
1327 gtk_action_set_visible (action, show_email_link);
1328 action = gtk_action_group_get_action (priv->action_group, "PopupCopyEmailAddress");
1329 gtk_action_set_visible (action, show_email_link);
1330 action = gtk_action_group_get_action (priv->action_group, "PopupCall");
1331 gtk_action_set_visible (action, show_call_link);
1332 action = gtk_action_group_get_action (priv->action_group, "PopupCopyCallAddress");
1333 gtk_action_set_visible (action, show_call_link);
1334 action = gtk_action_group_get_action (priv->action_group, "PopupOpenLink");
1335 gtk_action_set_visible (action, show_link);
1336 action = gtk_action_group_get_action (priv->action_group, "PopupCopyLinkAddress");
1337 gtk_action_set_visible (action, show_link);
1338
1339 action = gtk_action_group_get_action (priv->action_group, "PopupCloseWindow");
1340 gtk_action_set_visible (action, n_pages <= 1);
1341 action = gtk_action_group_get_action (priv->action_group, "PopupCloseTab");
1342 gtk_action_set_visible (action, n_pages > 1);
1343
1344 action = gtk_action_group_get_action (priv->action_group, "PopupCopy");
1345 gtk_action_set_sensitive (action, vte_terminal_get_has_selection (VTE_TERMINAL (screen)));
1346 action = gtk_action_group_get_action (priv->action_group, "PopupPaste");
1347 gtk_action_set_sensitive (action, can_paste);
1348 action = gtk_action_group_get_action (priv->action_group, "PopupPasteURIPaths");
1349 gtk_action_set_visible (action, can_paste_uris);
1350
1351 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
1352 "gtk-show-input-method-menu", &show_input_method_menu,
1353 NULL);
1354
1355 action = gtk_action_group_get_action (priv->action_group, "PopupInputMethods");
1356 gtk_action_set_visible (action, show_input_method_menu);
1357
1358 im_menu_item = gtk_ui_manager_get_widget (priv->ui_manager,
1359 "/Popup/PopupInputMethods");
1360 /* FIXME: fix this when gtk+ bug #500065 is done, use vte_terminal_im_merge_ui */
1361 if (show_input_method_menu)
1362 {
1363 im_menu = gtk_menu_new ();
1364 vte_terminal_im_append_menuitems (VTE_TERMINAL (screen),
1365 GTK_MENU_SHELL (im_menu));
1366 gtk_widget_show (im_menu);
1367 gtk_menu_item_set_submenu (GTK_MENU_ITEM (im_menu_item), im_menu);
1368 }
1369 else
1370 {
1371 gtk_menu_item_set_submenu (GTK_MENU_ITEM (im_menu_item), NULL);
1372 }
1373
1374 popup_menu = gtk_ui_manager_get_widget (priv->ui_manager, "/Popup");
1375 g_signal_connect (popup_menu, "deactivate",
1376 G_CALLBACK (popup_menu_deactivate_callback), window);
1377
1378 /* Pseudo activation of the popup menu's action */
1379 action = gtk_action_group_get_action (priv->action_group, "Popup");
1380 gtk_action_activate (action);
1381
1382 if (info->button == 0)
1383 gtk_menu_shell_select_first (GTK_MENU_SHELL (popup_menu), FALSE);
1384
1385 gtk_menu_popup (GTK_MENU (popup_menu),
1386 NULL, NULL,
1387 NULL, NULL,
1388 info->button,
1389 info->timestamp);
1390}
1391
1392static void
1393screen_show_popup_menu_callback (TerminalScreen *screen,
1394 TerminalScreenPopupInfo *info,
1395 TerminalWindow *window)
1396{
1397 GtkClipboard *clipboard;
1398
1399 g_return_if_fail (info->window == window);
1400
1401 clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), GDK_SELECTION_CLIPBOARD);
1402 gtk_clipboard_request_targets (clipboard,
1403 (GtkClipboardTargetsReceivedFunc) popup_clipboard_targets_received_cb,
1404 terminal_screen_popup_info_ref (info));
1405}
1406
1407static gboolean
1408screen_match_clicked_cb (TerminalScreen *screen,
1409 const char *match,
1410 int flavour,
1411 guint state,
1412 TerminalWindow *window)
1413{
1414 TerminalWindowPrivate *priv = window->priv;
1415
1416 if (screen != priv->active_screen)
1417 return FALSE;
1418
1419 switch (flavour)
1420 {
1421#ifdef ENABLE_SKEY
1422 case FLAVOR_SKEY:
1423 terminal_skey_do_popup (GTK_WINDOW (window), screen, match);
1424 break;
1425#endif
1426 default:
1427 gtk_widget_grab_focus (GTK_WIDGET (screen));
1428 terminal_util_open_url (GTK_WIDGET (window), match, flavour,
1429 gtk_get_current_event_time ());
1430 break;
1431 }
1432
1433 return TRUE;
1434}
1435
1436static void
1437screen_close_cb (TerminalScreen *screen,
1438 TerminalWindow *window)
1439{
1440 terminal_window_remove_screen (window, screen);
1441}
1442
1443static gboolean
1444terminal_window_accel_activate_cb (GtkAccelGroup *accel_group,
1445 GObject *acceleratable,
1446 guint keyval,
1447 GdkModifierType modifier,
1448 TerminalWindow *window)
1449{
1450 GtkAccelGroupEntry *entries;
1451 guint n_entries;
1452 gboolean retval = FALSE;
1453
1454 entries = gtk_accel_group_query (accel_group, keyval, modifier, &n_entries);
1455 if (n_entries > 0)
1456 {
1457 const char *accel_path;
1458
1459 accel_path = g_quark_to_string (entries[0].accel_path_quark);
1460
1461 if (g_str_has_prefix (accel_path, "<Actions>/Main/"))
1462 {
1463 const char *action_name;
1464
1465 /* We want to always consume these accelerators, even if the corresponding
1466 * action is insensitive, so the corresponding shortcut key escape code
1467 * isn't sent to the terminal. See bug #453193, bug #138609 and bug #559728.
1468 * This also makes tab cycling work, bug #92139. (NOT!)
1469 */
1470
1471 action_name = I_(accel_path + strlen ("<Actions>/Main/"));
1472
1473#if 0
1474 if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook)) > 1 &&
1475 (action_name == I_("TabsPrevious") || action_name == I_("TabsNext")))
1476 retval = TRUE;
1477 else
1478#endif
1479 if (action_name == I_("EditCopy") ||
1480 action_name == I_("PopupCopy") ||
1481 action_name == I_("EditPaste") ||
1482 action_name == I_("PopupPaste"))
1483 retval = TRUE;
1484 }
1485 }
1486
1487 return retval;
1488}
1489
1490/*****************************************/
1491
1492#ifdef GNOME_ENABLE_DEBUG
1493static void
1494terminal_window_size_request_cb (GtkWidget *widget,
1495 GtkRequisition *req)
1496{
1497 _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY,
1498 "[window %p] size-request result %d : %d\n",
1499 widget, req->width, req->height);
1500}
1501
1502static void
1503terminal_window_size_allocate_cb (GtkWidget *widget,
1504 GtkAllocation *allocation)
1505{
1506 _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY,
1507 "[window %p] size-alloc result %d : %d at (%d, %d)\n",
1508 widget,
1509 allocation->width, allocation->height,
1510 allocation->x, allocation->y);
1511}
1512#endif /* GNOME_ENABLE_DEBUG */
1513
1514static void
1515terminal_window_realize (GtkWidget *widget)
1516{
1517 TerminalWindow *window = TERMINAL_WINDOW (widget);
1518 TerminalWindowPrivate *priv = window->priv;
1519#ifdef GDK_WINDOWING_X11
1520 GdkScreen *screen;
1521 GdkColormap *colormap;
1522 GtkAllocation widget_allocation;
1523
1524 gtk_widget_get_allocation (widget, &widget_allocation);
1525 screen = gtk_widget_get_screen (GTK_WIDGET (window));
1526 if (gdk_screen_is_composited (screen) &&
1527 (colormap = gdk_screen_get_rgba_colormap (screen)) != NULL)
1528 {
1529 /* Set RGBA colormap if possible so VTE can use real transparency */
1530 gtk_widget_set_colormap (widget, colormap);
1531 priv->have_argb_visual = TRUE;
1532 }
1533 else
1534 {
1535 gtk_widget_set_colormap (widget, gdk_screen_get_default_colormap (screen));
1536 priv->have_argb_visual = FALSE;
1537 }
1538#endif
1539
1540 _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY,
1541 "[window %p] realize, size %d : %d at (%d, %d)\n",
1542 widget,
1543 widget_allocation.width, widget_allocation.height,
1544 widget_allocation.x, widget_allocation.y);
1545
1546 GTK_WIDGET_CLASS (terminal_window_parent_class)->realize (widget);
1547
1548 /* Need to do this now since this requires the window to be realized */
1549 if (priv->active_screen != NULL)
1550 sync_screen_icon_title (priv->active_screen, NULL, window);
1551}
1552
1553static gboolean
1554terminal_window_map_event (GtkWidget *widget,
1555 GdkEventAny *event)
1556{
1557 TerminalWindow *window = TERMINAL_WINDOW (widget);
1558 TerminalWindowPrivate *priv = window->priv;
1559 gboolean (* map_event) (GtkWidget *, GdkEventAny *) =
1560 GTK_WIDGET_CLASS (terminal_window_parent_class)->map_event;
1561 GtkAllocation widget_allocation;
1562
1563 gtk_widget_get_allocation (widget, &widget_allocation);
1564 _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY,
1565 "[window %p] map-event, size %d : %d at (%d, %d)\n",
1566 widget,
1567 widget_allocation.width, widget_allocation.height,
1568 widget_allocation.x, widget_allocation.y);
1569
1570 if (priv->clear_demands_attention)
1571 {
1572#ifdef GDK_WINDOWING_X11
1573 terminal_util_x11_clear_demands_attention (gtk_widget_get_window (widget));
1574#endif
1575
1576 priv->clear_demands_attention = FALSE;
1577 }
1578
1579 if (map_event)
1580 return map_event (widget, event);
1581
1582 return FALSE;
1583}
1584
1585
1586static gboolean
1587terminal_window_state_event (GtkWidget *widget,
1588 GdkEventWindowState *event)
1589{
1590 gboolean (* window_state_event) (GtkWidget *, GdkEventWindowState *event) =
1591 GTK_WIDGET_CLASS (terminal_window_parent_class)->window_state_event;
1592
1593 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
1594 {
1595 TerminalWindow *window = TERMINAL_WINDOW (widget);
1596 TerminalWindowPrivate *priv = window->priv;
1597 GtkAction *action;
1598 gboolean is_fullscreen;
1599
1600 is_fullscreen = (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) != 0;
1601
1602 action = gtk_action_group_get_action (priv->action_group, "ViewFullscreen");
1603 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), is_fullscreen);
1604
1605 action = gtk_action_group_get_action (priv->action_group, "PopupLeaveFullscreen");
1606 gtk_action_set_visible (action, is_fullscreen);
1607 }
1608
1609 if (window_state_event)
1610 return window_state_event (widget, event);
1611
1612 return FALSE;
1613}
1614
1615static void
1616terminal_window_window_manager_changed_cb (GdkScreen *screen,
1617 TerminalWindow *window)
1618{
1619 TerminalWindowPrivate *priv = window->priv;
1620 GtkAction *action;
1621 gboolean supports_fs;
1622
1623 supports_fs = gdk_x11_screen_supports_net_wm_hint (screen, gdk_atom_intern ("_NET_WM_STATE_FULLSCREEN", FALSE));
1624
1625 action = gtk_action_group_get_action (priv->action_group, "ViewFullscreen");
1626 gtk_action_set_sensitive (action, supports_fs);
1627}
1628
1629#ifdef GDK_WINDOWING_X11
1630
1631static void
1632terminal_window_composited_changed_cb (GdkScreen *screen,
1633 TerminalWindow *window)
1634{
1635 TerminalWindowPrivate *priv = window->priv;
1636 gboolean composited;
1637
1638 composited = gdk_screen_is_composited (screen);
1639 if ((composited != priv->have_argb_visual) &&
1640 gtk_widget_get_realized (GTK_WIDGET (window)))
1641 {
1642 GtkWidget *widget = GTK_WIDGET (window);
1643 GdkWindow *widget_window;
1644 guint32 user_time;
1645 gboolean have_desktop;
1646 guint32 desktop = 0; /* Quiet GCC */
1647 gboolean was_minimized;
1648 int x, y;
1649
1650 widget_window = gtk_widget_get_window (widget);
1651
1652 user_time = gdk_x11_display_get_user_time (gtk_widget_get_display (widget));
1653
1654 /* If compositing changed, re-realize the window. Bug #563561 */
1655
1656 /* Save the position; this isn't perfect, because the position
1657 * that gtk_window_get_position() returns is the position of the
1658 * frame window, and we are racing with the new window manager
1659 * framing our window, so we might see a funky intermediate state.
1660 * But at worst, we'll be off by a few pixels (the frame size). */
1661 gtk_window_get_position (GTK_WINDOW (window), &x, &y);
1662
1663 /* GtkWindow tries to save whether the window was iconified
1664 * and restore it, but that doesn't work because of problems
1665 * GDK_WINDOW_STATE_ICONIFIED. For details, see comment for
1666 * terminal_util_x11_window_is_minimized()
1667 */
1668 was_minimized = terminal_util_x11_window_is_minimized (widget_window);
1669
1670 /* And the desktop */
1671 have_desktop = terminal_util_x11_get_net_wm_desktop (widget_window, &desktop);
1672
1673 gtk_widget_hide (widget);
1674 gtk_widget_unrealize (widget);
1675
1676 /* put the window back where it was before */
1677 gtk_window_move (GTK_WINDOW (window), x, y);
1678 gtk_widget_realize (widget);
1679
1680 /* Get new GdkWindow */
1681 widget_window = gtk_widget_get_window (widget);
1682
1683 gdk_x11_window_set_user_time (widget_window, user_time);
1684
1685 if (was_minimized)
1686 gtk_window_iconify (GTK_WINDOW (window));
1687 else
1688 gtk_window_deiconify (GTK_WINDOW (window));
1689
1690 gtk_widget_show (widget);
1691 if (have_desktop)
1692 terminal_util_x11_set_net_wm_desktop (widget_window, desktop);
1693
1694 /* Mapping the window is likely to have set the "demands-attention" state.
1695 * In particular, Metacity will always set the state if a window is mapped,
1696 * is not given the focus (because of an old user time), and is covered
1697 * by some other window. We have no way of preventing this, so we just
1698 * wait for our window to be mapped, and then tell the window manager
1699 * to turn off the bit. If it wasn't set, no harm.
1700 */
1701 priv->clear_demands_attention = TRUE;
1702 }
1703}
1704
1705#endif /* GDK_WINDOWING_X11 */
1706
1707static void
1708terminal_window_screen_update (TerminalWindow *window,
1709 GdkScreen *screen)
1710{
1711 TerminalApp *app;
1712
1713 terminal_window_window_manager_changed_cb (screen, window);
1714 g_signal_connect (screen, "window-manager-changed",
1715 G_CALLBACK (terminal_window_window_manager_changed_cb), window);
1716#ifdef GDK_WINDOWING_X11
1717 g_signal_connect (screen, "composited-changed",
1718 G_CALLBACK (terminal_window_composited_changed_cb), window);
1719#endif
1720
1721 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (screen), "GT::HasSettingsConnection")))
1722 return;
1723
1724 g_object_set_data_full (G_OBJECT (screen), "GT::HasSettingsConnection",
1725 GINT_TO_POINTER (TRUE),
1726 (GDestroyNotify) app_setting_notify_destroy_cb);
1727
1728 app = terminal_app_get ();
1729 app_setting_notify_cb (app, NULL, screen);
1730 g_signal_connect (app, "notify::" TERMINAL_APP_ENABLE_MNEMONICS,
1731 G_CALLBACK (app_setting_notify_cb), screen);
1732 g_signal_connect (app, "notify::" TERMINAL_APP_ENABLE_MENU_BAR_ACCEL,
1733 G_CALLBACK (app_setting_notify_cb), screen);
1734}
1735
1736static void
1737terminal_window_screen_changed (GtkWidget *widget,
1738 GdkScreen *previous_screen)
1739{
1740 TerminalWindow *window = TERMINAL_WINDOW (widget);
1741 void (* screen_changed) (GtkWidget *, GdkScreen *) =
1742 GTK_WIDGET_CLASS (terminal_window_parent_class)->screen_changed;
1743 GdkScreen *screen;
1744
1745 if (screen_changed)
1746 screen_changed (widget, previous_screen);
1747
1748 screen = gtk_widget_get_screen (widget);
1749 if (previous_screen == screen)
1750 return;
1751
1752 if (previous_screen)
1753 {
1754 g_signal_handlers_disconnect_by_func (previous_screen,
1755 G_CALLBACK (terminal_window_window_manager_changed_cb),
1756 window);
1757#ifdef GDK_WINDOWING_X11
1758 g_signal_handlers_disconnect_by_func (previous_screen,
1759 G_CALLBACK (terminal_window_composited_changed_cb),
1760 window);
1761#endif
1762 }
1763
1764 if (!screen)
1765 return;
1766
1767 terminal_window_screen_update (window, screen);
1768}
1769
1770static void
1771terminal_window_profile_list_changed_cb (TerminalApp *app,
1772 TerminalWindow *window)
1773{
1774 terminal_window_update_set_profile_menu (window);
1775 terminal_window_update_new_terminal_menus (window);
1776}
1777
1778static void
1779terminal_window_encoding_list_changed_cb (TerminalApp *app,
1780 TerminalWindow *window)
1781{
1782 terminal_window_update_encoding_menu (window);
1783}
1784
1785static void
1786terminal_window_init (TerminalWindow *window)
1787{
1788 const GtkActionEntry menu_entries[] =
1789 {
1790 /* Toplevel */
1791 { "File", NULL, N_("_File") },
1792 { "FileNewWindowProfiles", STOCK_NEW_WINDOW, N_("Open _Terminal")},
1793 { "FileNewTabProfiles", STOCK_NEW_TAB, N_("Open Ta_b") },
1794 { "Edit", NULL, N_("_Edit") },
1795 { "View", NULL, N_("_View") },
1796 { "Search", NULL, N_("_Search") },
1797 { "Terminal", NULL, N_("_Terminal") },
1798 { "Tabs", NULL, N_("Ta_bs") },
1799 { "Help", NULL, N_("_Help") },
1800 { "Popup", NULL, NULL },
1801 { "NotebookPopup", NULL, "" },
1802
1803 /* File menu */
1804 { "FileNewWindow", STOCK_NEW_WINDOW, N_("Open _Terminal"), "<shift><control>N",
1805 NULL,
1806 G_CALLBACK (file_new_window_callback) },
1807 { "FileNewTab", STOCK_NEW_TAB, N_("Open Ta_b"), "<shift><control>T",
1808 NULL,
1809 G_CALLBACK (file_new_tab_callback) },
1810 { "FileNewProfile", GTK_STOCK_OPEN, N_("New _Profile…"), "",
1811 NULL,
1812 G_CALLBACK (file_new_profile_callback) },
1813 { "FileSaveContents", GTK_STOCK_SAVE, N_("_Save Contents"), "",
1814 NULL,
1815 G_CALLBACK (file_save_contents_callback) },
1816 { "FileCloseTab", GTK_STOCK_CLOSE, N_("C_lose Tab"), "<shift><control>W",
1817 NULL,
1818 G_CALLBACK (file_close_tab_callback) },
1819 { "FileCloseWindow", GTK_STOCK_CLOSE, N_("_Close Window"), "<shift><control>Q",
1820 NULL,
1821 G_CALLBACK (file_close_window_callback) },
1822
1823 /* Edit menu */
1824 { "EditCopy", GTK_STOCK_COPY, NULL, "<shift><control>C",
1825 NULL,
1826 G_CALLBACK (edit_copy_callback) },
1827 { "EditPaste", GTK_STOCK_PASTE, NULL, "<shift><control>V",
1828 NULL,
1829 G_CALLBACK (edit_paste_callback) },
1830 { "EditPasteURIPaths", GTK_STOCK_PASTE, N_("Paste _Filenames"), "",
1831 NULL,
1832 G_CALLBACK (edit_paste_callback) },
1833 { "EditSelectAll", GTK_STOCK_SELECT_ALL, NULL, NULL,
1834 NULL,
1835 G_CALLBACK (edit_select_all_callback) },
1836 { "EditProfiles", NULL, N_("P_rofiles…"), NULL,
1837 NULL,
1838 G_CALLBACK (edit_profiles_callback) },
1839 { "EditKeybindings", NULL, N_("_Keyboard Shortcuts…"), NULL,
1840 NULL,
1841 G_CALLBACK (edit_keybindings_callback) },
1842 { "EditCurrentProfile", NULL, N_("Pr_ofile Preferences"), NULL,
1843 NULL,
1844 G_CALLBACK (edit_current_profile_callback) },
1845
1846 /* View menu */
1847 { "ViewZoomIn", GTK_STOCK_ZOOM_IN, NULL, "<control>plus",
1848 NULL,
1849 G_CALLBACK (view_zoom_in_callback) },
1850 { "ViewZoomOut", GTK_STOCK_ZOOM_OUT, NULL, "<control>minus",
1851 NULL,
1852 G_CALLBACK (view_zoom_out_callback) },
1853 { "ViewZoom100", GTK_STOCK_ZOOM_100, NULL, "<control>0",
1854 NULL,
1855 G_CALLBACK (view_zoom_normal_callback) },
1856
1857 /* Search menu */
1858 { "SearchFind", GTK_STOCK_FIND, N_("_Find..."), "<shift><control>F",
1859 NULL,
1860 G_CALLBACK (search_find_callback) },
1861 { "SearchFindNext", NULL, N_("Find Ne_xt"), "<shift><control>H",
1862 NULL,
1863 G_CALLBACK (search_find_next_callback) },
1864 { "SearchFindPrevious", NULL, N_("Find Pre_vious"), "<shift><control>G",
1865 NULL,
1866 G_CALLBACK (search_find_prev_callback) },
1867 { "SearchClearHighlight", NULL, N_("_Clear Highlight"), "<shift><control>J",
1868 NULL,
1869 G_CALLBACK (search_clear_highlight_callback) },
1870#if 0
1871 { "SearchGoToLine", GTK_STOCK_JUMP_TO, N_("Go to _Line..."), "<shift><control>I",
1872 NULL,
1873 G_CALLBACK (search_goto_line_callback) },
1874 { "SearchIncrementalSearch", GTK_STOCK_FIND, N_("_Incremental Search..."), "<shift><control>K",
1875 NULL,
1876 G_CALLBACK (search_incremental_search_callback) },
1877#endif
1878
1879 /* Terminal menu */
1880 { "TerminalProfiles", NULL, N_("Change _Profile") },
1881 { "TerminalSetTitle", NULL, N_("_Set Title…"), NULL,
1882 NULL,
1883 G_CALLBACK (terminal_set_title_callback) },
1884 { "TerminalSetEncoding", NULL, N_("Set _Character Encoding") },
1885 { "TerminalReset", NULL, N_("_Reset"), NULL,
1886 NULL,
1887 G_CALLBACK (terminal_reset_callback) },
1888 { "TerminalResetClear", NULL, N_("Reset and C_lear"), NULL,
1889 NULL,
1890 G_CALLBACK (terminal_reset_clear_callback) },
1891
1892 /* Terminal/Encodings menu */
1893 { "TerminalAddEncoding", NULL, N_("_Add or Remove…"), NULL,
1894 NULL,
1895 G_CALLBACK (terminal_add_encoding_callback) },
1896
1897 /* Tabs menu */
1898 { "TabsPrevious", NULL, N_("_Previous Tab"), "<control>Page_Up",
1899 NULL,
1900 G_CALLBACK (tabs_next_or_previous_tab_cb) },
1901 { "TabsNext", NULL, N_("_Next Tab"), "<control>Page_Down",
1902 NULL,
1903 G_CALLBACK (tabs_next_or_previous_tab_cb) },
1904 { "TabsMoveLeft", NULL, N_("Move Tab _Left"), "<shift><control>Page_Up",
1905 NULL,
1906 G_CALLBACK (tabs_move_left_callback) },
1907 { "TabsMoveRight", NULL, N_("Move Tab _Right"), "<shift><control>Page_Down",
1908 NULL,
1909 G_CALLBACK (tabs_move_right_callback) },
1910 { "TabsDetach", NULL, N_("_Detach tab"), NULL,
1911 NULL,
1912 G_CALLBACK (tabs_detach_tab_callback) },
1913
1914 /* Help menu */
1915 { "HelpContents", GTK_STOCK_HELP, N_("_Contents"), "F1",
1916 NULL,
1917 G_CALLBACK (help_contents_callback) },
1918 { "HelpAbout", GTK_STOCK_ABOUT, N_("_About"), NULL,
1919 NULL,
1920 G_CALLBACK (help_about_callback) },
1921
1922 /* Popup menu */
1923 { "PopupSendEmail", NULL, N_("_Send Mail To…"), NULL,
1924 NULL,
1925 G_CALLBACK (popup_open_url_callback) },
1926 { "PopupCopyEmailAddress", NULL, N_("_Copy E-mail Address"), NULL,
1927 NULL,
1928 G_CALLBACK (popup_copy_url_callback) },
1929 { "PopupCall", NULL, N_("C_all To…"), NULL,
1930 NULL,
1931 G_CALLBACK (popup_open_url_callback) },
1932 { "PopupCopyCallAddress", NULL, N_("_Copy Call Address"), NULL,
1933 NULL,
1934 G_CALLBACK (popup_copy_url_callback) },
1935 { "PopupOpenLink", NULL, N_("_Open Link"), NULL,
1936 NULL,
1937 G_CALLBACK (popup_open_url_callback) },
1938 { "PopupCopyLinkAddress", NULL, N_("_Copy Link Address"), NULL,
1939 NULL,
1940 G_CALLBACK (popup_copy_url_callback) },
1941 { "PopupTerminalProfiles", NULL, N_("P_rofiles") },
1942 { "PopupCopy", GTK_STOCK_COPY, NULL, "",
1943 NULL,
1944 G_CALLBACK (edit_copy_callback) },
1945 { "PopupPaste", GTK_STOCK_PASTE, NULL, "",
1946 NULL,
1947 G_CALLBACK (edit_paste_callback) },
1948 { "PopupPasteURIPaths", GTK_STOCK_PASTE, N_("Paste _Filenames"), "",
1949 NULL,
1950 G_CALLBACK (edit_paste_callback) },
1951 { "PopupNewTerminal", NULL, N_("Open _Terminal"), NULL,
1952 NULL,
1953 G_CALLBACK (file_new_window_callback) },
1954 { "PopupNewTab", NULL, N_("Open Ta_b"), NULL,
1955 NULL,
1956 G_CALLBACK (file_new_tab_callback) },
1957 { "PopupCloseWindow", NULL, N_("C_lose Window"), NULL,
1958 NULL,
1959 G_CALLBACK (file_close_window_callback) },
1960 { "PopupCloseTab", NULL, N_("C_lose Tab"), NULL,
1961 NULL,
1962 G_CALLBACK (file_close_tab_callback) },
1963 { "PopupLeaveFullscreen", NULL, N_("L_eave Full Screen"), NULL,
1964 NULL,
1965 G_CALLBACK (popup_leave_fullscreen_callback) },
1966 { "PopupInputMethods", NULL, N_("_Input Methods") }
1967 };
1968
1969 const GtkToggleActionEntry toggle_menu_entries[] =
1970 {
1971 /* View Menu */
1972 { "ViewMenubar", NULL, N_("Show _Menubar"), NULL,
1973 NULL,
1974 G_CALLBACK (view_menubar_toggled_callback),
1975 FALSE },
1976 { "ViewFullscreen", NULL, N_("_Full Screen"), NULL,
1977 NULL,
1978 G_CALLBACK (view_fullscreen_toggled_callback),
1979 FALSE }
1980 };
1981 TerminalWindowPrivate *priv;
1982 TerminalApp *app;
1983 GtkActionGroup *action_group;
1984 GtkAction *action;
1985 GtkUIManager *manager;
1986 GtkWidget *main_vbox;
1987 GError *error;
1988 GtkWindowGroup *window_group;
1989 GtkAccelGroup *accel_group;
1990
1991 priv = window->priv = G_TYPE_INSTANCE_GET_PRIVATE (window, TERMINAL_TYPE_WINDOW, TerminalWindowPrivate);
1992
1993 g_signal_connect (G_OBJECT (window), "delete_event",
1994 G_CALLBACK(terminal_window_delete_event),
1995 NULL);
1996#ifdef GNOME_ENABLE_DEBUG
1997 _TERMINAL_DEBUG_IF (TERMINAL_DEBUG_GEOMETRY)
1998 {
1999 g_signal_connect_after (window, "size-request", G_CALLBACK (terminal_window_size_request_cb), NULL);
2000 g_signal_connect_after (window, "size-allocate", G_CALLBACK (terminal_window_size_allocate_cb), NULL);
2001 }
2002#endif
2003
2004 gtk_window_set_title (GTK_WINDOW (window), _("Terminal"));
2005
2006 priv->active_screen = NULL;
2007 priv->menubar_visible = FALSE;
2008
2009 main_vbox = gtk_vbox_new (FALSE, 0);
2010 gtk_container_add (GTK_CONTAINER (window), main_vbox);
2011 gtk_widget_show (main_vbox);
2012
2013 priv->notebook = gtk_notebook_new ();
2014 gtk_notebook_set_scrollable (GTK_NOTEBOOK (priv->notebook), TRUE);
2015 gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
2016 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
2017 gtk_notebook_set_group (GTK_NOTEBOOK (priv->notebook), GUINT_TO_POINTER (1));
2018 gtk_notebook_set_scrollable (GTK_NOTEBOOK (priv->notebook),
2019 TRUE);
2020 g_signal_connect (priv->notebook, "button-press-event",
2021 G_CALLBACK (notebook_button_press_cb), window);
2022 g_signal_connect (priv->notebook, "popup-menu",
2023 G_CALLBACK (notebook_popup_menu_cb), window);
2024 g_signal_connect_after (priv->notebook, "switch-page",
2025 G_CALLBACK (notebook_page_selected_callback), window);
2026 g_signal_connect_after (priv->notebook, "page-added",
2027 G_CALLBACK (notebook_page_added_callback), window);
2028 g_signal_connect_after (priv->notebook, "page-removed",
2029 G_CALLBACK (notebook_page_removed_callback), window);
2030 g_signal_connect_data (priv->notebook, "page-reordered",
2031 G_CALLBACK (terminal_window_update_tabs_menu_sensitivity),
2032 window, NULL, G_CONNECT_SWAPPED | G_CONNECT_AFTER);
2033
2034 gtk_box_pack_end (GTK_BOX (main_vbox), priv->notebook, TRUE, TRUE, 0);
2035 gtk_widget_show (priv->notebook);
2036
2037 priv->old_char_width = -1;
2038 priv->old_char_height = -1;
2039 priv->old_geometry_widget = NULL;
2040
2041 /* Create the UI manager */
2042 manager = priv->ui_manager = gtk_ui_manager_new ();
2043
2044 accel_group = gtk_ui_manager_get_accel_group (manager);
2045 gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
2046 /* Workaround for bug #453193, bug #138609 and bug #559728 */
2047 g_signal_connect_after (accel_group, "accel-activate",
2048 G_CALLBACK (terminal_window_accel_activate_cb), window);
2049
2050 /* Create the actions */
2051 /* Note that this action group name is used in terminal-accels.c; do not change it */
2052 priv->action_group = action_group = gtk_action_group_new ("Main");
2053 gtk_action_group_set_translation_domain (action_group, NULL);
2054 gtk_action_group_add_actions (action_group, menu_entries,
2055 G_N_ELEMENTS (menu_entries), window);
2056 gtk_action_group_add_toggle_actions (action_group,
2057 toggle_menu_entries,
2058 G_N_ELEMENTS (toggle_menu_entries),
2059 window);
2060 gtk_ui_manager_insert_action_group (manager, action_group, 0);
2061 g_object_unref (action_group);
2062
2063 action = gtk_action_group_get_action (action_group, "Edit");
2064 g_signal_connect (action, "activate",
2065 G_CALLBACK (edit_menu_activate_callback), window);
2066
2067 /* Set this action invisible so the Edit menu doesn't flash the first
2068 * time it's shown and there's no text/uri-list on the clipboard.
2069 */
2070 action = gtk_action_group_get_action (priv->action_group, "EditPasteURIPaths");
2071 gtk_action_set_visible (action, FALSE);
2072
2073 /* Idem for this action, since the window is not fullscreen. */
2074 action = gtk_action_group_get_action (priv->action_group, "PopupLeaveFullscreen");
2075 gtk_action_set_visible (action, FALSE);
2076
2077#ifndef ENABLE_SAVE
2078 action = gtk_action_group_get_action (priv->action_group, "FileSaveContents");
2079 gtk_action_set_visible (action, FALSE);
2080#endif
2081
2082 /* Load the UI */
2083 error = NULL;
2084 priv->ui_id = gtk_ui_manager_add_ui_from_file (manager,
2085 TERM_PKGDATADIR G_DIR_SEPARATOR_S "terminal.xml",
2086 &error);
2087 if (error)
2088 {
2089 g_printerr ("Failed to load UI: %s\n", error->message);
2090 g_error_free (error);
2091 }
2092
2093 priv->menubar = gtk_ui_manager_get_widget (manager, "/menubar");
2094 gtk_box_pack_start (GTK_BOX (main_vbox),
2095 priv->menubar,
2096 FALSE, FALSE, 0);
2097
2098 /* Add tabs menu */
2099 priv->tabs_menu = terminal_tabs_menu_new (window);
2100
2101 app = terminal_app_get ();
2102 terminal_window_profile_list_changed_cb (app, window);
2103 g_signal_connect (app, "profile-list-changed",
2104 G_CALLBACK (terminal_window_profile_list_changed_cb), window);
2105
2106 terminal_window_encoding_list_changed_cb (app, window);
2107 g_signal_connect (app, "encoding-list-changed",
2108 G_CALLBACK (terminal_window_encoding_list_changed_cb), window);
2109
2110 terminal_window_set_menubar_visible (window, TRUE);
2111 priv->use_default_menubar_visibility = TRUE;
2112
2113 terminal_window_update_size_to_menu (window);
2114
2115 /* We have to explicitly call this, since screen-changed is NOT
2116 * emitted for the toplevel the first time!
2117 */
2118 terminal_window_screen_update (window, gtk_widget_get_screen (GTK_WIDGET (window)));
2119
2120 window_group = gtk_window_group_new ();
2121 gtk_window_group_add_window (window_group, GTK_WINDOW (window));
2122 g_object_unref (window_group);
2123
2124 terminal_util_set_unique_role (GTK_WINDOW (window), "gnome-terminal-window");
2125}
2126
2127static void
2128terminal_window_class_init (TerminalWindowClass *klass)
2129{
2130 GObjectClass *object_class = G_OBJECT_CLASS (klass);
2131 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
2132
2133 object_class->dispose = terminal_window_dispose;
2134 object_class->finalize = terminal_window_finalize;
2135
2136 widget_class->show = terminal_window_show;
2137 widget_class->realize = terminal_window_realize;
2138 widget_class->map_event = terminal_window_map_event;
2139 widget_class->window_state_event = terminal_window_state_event;
2140 widget_class->screen_changed = terminal_window_screen_changed;
2141
2142 g_type_class_add_private (object_class, sizeof (TerminalWindowPrivate));
2143
2144 gtk_rc_parse_string ("style \"gnome-terminal-tab-close-button-style\"\n"
2145 "{\n"
2146 "GtkWidget::focus-padding = 0\n"
2147 "GtkWidget::focus-line-width = 0\n"
2148 "xthickness = 0\n"
2149 "ythickness = 0\n"
2150 "}\n"
2151 "widget \"*.gnome-terminal-tab-close-button\" style \"gnome-terminal-tab-close-button-style\"");
2152
2153 gtk_notebook_set_window_creation_hook (handle_tab_droped_on_desktop, NULL, NULL);
2154}
2155
2156static void
2157terminal_window_dispose (GObject *object)
2158{
2159 TerminalWindow *window = TERMINAL_WINDOW (object);
2160 TerminalWindowPrivate *priv = window->priv;
2161 TerminalApp *app;
2162 GdkScreen *screen;
2163
2164 remove_popup_info (window);
2165
2166 priv->disposed = TRUE;
2167
2168 if (priv->tabs_menu)
2169 {
2170 g_object_unref (priv->tabs_menu);
2171 priv->tabs_menu = NULL;
2172 }
2173
2174 if (priv->profiles_action_group != NULL)
2175 disconnect_profiles_from_actions_in_group (priv->profiles_action_group);
2176 if (priv->new_terminal_action_group != NULL)
2177 disconnect_profiles_from_actions_in_group (priv->new_terminal_action_group);
2178
2179 app = terminal_app_get ();
2180 g_signal_handlers_disconnect_by_func (app,
2181 G_CALLBACK (terminal_window_profile_list_changed_cb),
2182 window);
2183 g_signal_handlers_disconnect_by_func (app,
2184 G_CALLBACK (terminal_window_encoding_list_changed_cb),
2185 window);
2186
2187 screen = gtk_widget_get_screen (GTK_WIDGET (object));
2188 if (screen)
2189 {
2190 g_signal_handlers_disconnect_by_func (screen,
2191 G_CALLBACK (terminal_window_window_manager_changed_cb),
2192 window);
2193#ifdef GDK_WINDOWING_X11
2194 g_signal_handlers_disconnect_by_func (screen,
2195 G_CALLBACK (terminal_window_composited_changed_cb),
2196 window);
2197#endif
2198 }
2199
2200 G_OBJECT_CLASS (terminal_window_parent_class)->dispose (object);
2201}
2202
2203static void
2204terminal_window_finalize (GObject *object)
2205{
2206 TerminalWindow *window = TERMINAL_WINDOW (object);
2207 TerminalWindowPrivate *priv = window->priv;
2208
2209 g_object_unref (priv->ui_manager);
2210
2211 if (priv->confirm_close_dialog)
2212 gtk_dialog_response (GTK_DIALOG (priv->confirm_close_dialog),
2213 GTK_RESPONSE_DELETE_EVENT);
2214
2215 if (priv->search_find_dialog)
2216 gtk_dialog_response (GTK_DIALOG (priv->search_find_dialog),
2217 GTK_RESPONSE_DELETE_EVENT);
2218
2219 G_OBJECT_CLASS (terminal_window_parent_class)->finalize (object);
2220}
2221
2222static gboolean
2223terminal_window_delete_event (GtkWidget *widget,
2224 GdkEvent *event,
2225 gpointer data)
2226{
2227 return confirm_close_window_or_tab (TERMINAL_WINDOW (widget), NULL);
2228}
2229
2230static void
2231terminal_window_show (GtkWidget *widget)
2232{
2233 TerminalWindow *window = TERMINAL_WINDOW (widget);
2234 GtkAllocation widget_allocation;
2235
2236 gtk_widget_get_allocation (widget, &widget_allocation);
2237
2238#if 0
2239 TerminalWindowPrivate *priv = window->priv;
2240
2241 if (priv->active_screen != NULL)
2242 {
2243 /* At this point, we have our GdkScreen, and hence the right
2244 * font size, so we can go ahead and size the window. */
2245 terminal_window_set_size (window, priv->active_screen, FALSE);
2246 }
2247#endif
2248
2249 terminal_window_update_geometry (window);
2250
2251 _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY,
2252 "[window %p] show, size %d : %d at (%d, %d)\n",
2253 widget,
2254 widget_allocation.width, widget_allocation.height,
2255 widget_allocation.x, widget_allocation.y);
2256
2257 GTK_WIDGET_CLASS (terminal_window_parent_class)->show (widget);
2258}
2259
2260TerminalWindow*
2261terminal_window_new (void)
2262{
2263 return g_object_new (TERMINAL_TYPE_WINDOW, NULL);
2264}
2265
2266/**
2267 * terminal_window_set_is_restored:
2268 * @window:
2269 *
2270 * Marks the window as restored from session.
2271 */
2272void
2273terminal_window_set_is_restored (TerminalWindow *window)
2274{
2275 g_return_if_fail (TERMINAL_IS_WINDOW (window));
2276 g_return_if_fail (!gtk_widget_get_mapped (GTK_WIDGET (window)));
2277
2278 window->priv->clear_demands_attention = TRUE;
2279}
2280
2281static void
2282profile_set_callback (TerminalScreen *screen,
2283 TerminalProfile *old_profile,
2284 TerminalWindow *window)
2285{
2286 TerminalWindowPrivate *priv = window->priv;
2287
2288 if (!gtk_widget_get_realized (GTK_WIDGET (window)))
2289 return;
2290
2291 if (screen != priv->active_screen)
2292 return;
2293
2294 terminal_window_update_set_profile_menu_active_profile (window);
2295}
2296
2297static void
2298sync_screen_title (TerminalScreen *screen,
2299 GParamSpec *psepc,
2300 TerminalWindow *window)
2301{
2302 TerminalWindowPrivate *priv = window->priv;
2303
2304 if (screen != priv->active_screen)
2305 return;
2306
2307 gtk_window_set_title (GTK_WINDOW (window), terminal_screen_get_title (screen));
2308}
2309
2310static void
2311sync_screen_icon_title (TerminalScreen *screen,
2312 GParamSpec *psepc,
2313 TerminalWindow *window)
2314{
2315 TerminalWindowPrivate *priv = window->priv;
2316
2317 if (!gtk_widget_get_realized (GTK_WIDGET (window)))
2318 return;
2319
2320 if (screen != priv->active_screen)
2321 return;
2322
2323 if (!terminal_screen_get_icon_title_set (screen))
2324 return;
2325
2326 gdk_window_set_icon_name (gtk_widget_get_window (GTK_WIDGET (window)), terminal_screen_get_icon_title (screen));
2327
2328 priv->icon_title_set = TRUE;
2329}
2330
2331static void
2332sync_screen_icon_title_set (TerminalScreen *screen,
2333 GParamSpec *psepc,
2334 TerminalWindow *window)
2335{
2336 TerminalWindowPrivate *priv = window->priv;
2337
2338 if (!gtk_widget_get_realized (GTK_WIDGET (window)))
2339 return;
2340
2341 /* No need to restore the title if we never set an icon title */
2342 if (!priv->icon_title_set)
2343 return;
2344
2345 if (screen != priv->active_screen)
2346 return;
2347
2348 if (terminal_screen_get_icon_title_set (screen))
2349 return;
2350
2351 /* Need to reset the icon name */
2352 /* FIXME: Once gtk+ bug 535557 is fixed, use that to unset the icon title. */
2353
2354 g_object_set_qdata (G_OBJECT (gtk_widget_get_window (GTK_WIDGET (window))),
2355 g_quark_from_static_string ("gdk-icon-name-set"),
2356 GUINT_TO_POINTER (FALSE));
2357 priv->icon_title_set = FALSE;
2358
2359 /* Re-setting the right title will be done by the notify::title handler which comes after this one */
2360}
2361
2362/* Notebook callbacks */
2363
2364static void
2365close_button_clicked_cb (GtkWidget *tab_label,
2366 GtkWidget *screen_container)
2367{
2368 GtkWidget *toplevel;
2369 TerminalWindow *window;
2370 TerminalWindowPrivate *priv;
2371 TerminalScreen *screen;
2372
2373 toplevel = gtk_widget_get_toplevel (screen_container);
2374 if (!gtk_widget_is_toplevel (toplevel))
2375 return;
2376
2377 if (!TERMINAL_IS_WINDOW (toplevel))
2378 return;
2379
2380 window = TERMINAL_WINDOW (toplevel);
2381 priv = window->priv;
2382
2383 screen = terminal_screen_container_get_screen (TERMINAL_SCREEN_CONTAINER (screen_container));
2384 if (confirm_close_window_or_tab (window, screen))
2385 return;
2386
2387 terminal_window_remove_screen (window, screen);
2388}
2389
2390void
2391terminal_window_add_screen (TerminalWindow *window,
2392 TerminalScreen *screen,
2393 int position)
2394{
2395 TerminalWindowPrivate *priv = window->priv;
2396 GtkWidget *old_window;
2397 GtkWidget *screen_container, *tab_label;
2398
2399 old_window = gtk_widget_get_toplevel (GTK_WIDGET (screen));
2400 if (gtk_widget_is_toplevel (old_window) &&
2401 TERMINAL_IS_WINDOW (old_window) &&
2402 TERMINAL_WINDOW (old_window)== window)
2403 return;
2404
2405 if (TERMINAL_IS_WINDOW (old_window))
2406 terminal_window_remove_screen (TERMINAL_WINDOW (old_window), screen);
2407
2408 screen_container = terminal_screen_container_new (screen);
2409 gtk_widget_show (screen_container);
2410
2411 update_tab_visibility (window, +1);
2412
2413 tab_label = terminal_tab_label_new (screen);
2414 g_signal_connect (tab_label, "close-button-clicked",
2415 G_CALLBACK (close_button_clicked_cb), screen_container);
2416
2417 gtk_notebook_insert_page (GTK_NOTEBOOK (priv->notebook),
2418 screen_container,
2419 tab_label,
2420 position);
2421 gtk_container_child_set (GTK_CONTAINER (priv->notebook),
2422 screen_container,
2423 "tab-expand", TRUE,
2424 "tab-fill", TRUE,
2425 NULL);
2426 gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (priv->notebook),
2427 screen_container,
2428 TRUE);
2429 gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (priv->notebook),
2430 screen_container,
2431 TRUE);
2432}
2433
2434void
2435terminal_window_remove_screen (TerminalWindow *window,
2436 TerminalScreen *screen)
2437{
2438 TerminalWindowPrivate *priv = window->priv;
2439 TerminalScreenContainer *screen_container;
2440
2441 g_return_if_fail (gtk_widget_get_toplevel (GTK_WIDGET (screen)) == GTK_WIDGET (window));
2442
2443 update_tab_visibility (window, -1);
2444
2445 screen_container = terminal_screen_container_get_from_screen (screen);
2446 gtk_container_remove (GTK_CONTAINER (priv->notebook),
2447 GTK_WIDGET (screen_container));
2448}
2449
2450void
2451terminal_window_move_screen (TerminalWindow *source_window,
2452 TerminalWindow *dest_window,
2453 TerminalScreen *screen,
2454 int dest_position)
2455{
2456 TerminalScreenContainer *screen_container;
2457
2458 g_return_if_fail (TERMINAL_IS_WINDOW (source_window));
2459 g_return_if_fail (TERMINAL_IS_WINDOW (dest_window));
2460 g_return_if_fail (TERMINAL_IS_SCREEN (screen));
2461 g_return_if_fail (gtk_widget_get_toplevel (GTK_WIDGET (screen)) == GTK_WIDGET (source_window));
2462 g_return_if_fail (dest_position >= -1);
2463
2464 screen_container = terminal_screen_container_get_from_screen (screen);
2465 g_assert (TERMINAL_IS_SCREEN_CONTAINER (screen_container));
2466
2467 /* We have to ref the screen container as well as the screen,
2468 * because otherwise removing the screen container from the source
2469 * window's notebook will cause the container and its containing
2470 * screen to be gtk_widget_destroy()ed!
2471 */
2472 g_object_ref_sink (screen_container);
2473 g_object_ref_sink (screen);
2474 terminal_window_remove_screen (source_window, screen);
2475
2476 /* Now we can safely remove the screen from the container and let the container die */
2477 gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (GTK_WIDGET (screen))), GTK_WIDGET (screen));
2478 g_object_unref (screen_container);
2479
2480 terminal_window_add_screen (dest_window, screen, dest_position);
2481 g_object_unref (screen);
2482}
2483
2484GList*
2485terminal_window_list_screen_containers (TerminalWindow *window)
2486{
2487 TerminalWindowPrivate *priv = window->priv;
2488
2489 /* We are trusting that GtkNotebook will return pages in order */
2490 return gtk_container_get_children (GTK_CONTAINER (priv->notebook));
2491}
2492
2493void
2494terminal_window_set_menubar_visible (TerminalWindow *window,
2495 gboolean setting)
2496{
2497 TerminalWindowPrivate *priv = window->priv;
2498 GtkAction *action;
2499
2500 /* it's been set now, so don't override when adding a screen.
2501 * this side effect must happen before we short-circuit below.
2502 */
2503 priv->use_default_menubar_visibility = FALSE;
2504
2505 if (setting == priv->menubar_visible)
2506 return;
2507
2508 priv->menubar_visible = setting;
2509
2510 action = gtk_action_group_get_action (priv->action_group, "ViewMenubar");
2511 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), setting);
2512
2513 g_object_set (priv->menubar, "visible", setting, NULL);
2514
2515 /* FIXMEchpe: use gtk_widget_get_realized instead? */
2516 if (priv->active_screen)
2517 {
2518 _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY,
2519 "[window %p] setting size after toggling menubar visibility\n",
2520 window);
2521
2522 terminal_window_set_size (window, priv->active_screen, TRUE);
2523 }
2524}
2525
2526gboolean
2527terminal_window_get_menubar_visible (TerminalWindow *window)
2528{
2529 TerminalWindowPrivate *priv = window->priv;
2530
2531 return priv->menubar_visible;
2532}
2533
2534GtkWidget *
2535terminal_window_get_notebook (TerminalWindow *window)
2536{
2537 TerminalWindowPrivate *priv = window->priv;
2538
2539 g_return_val_if_fail (TERMINAL_IS_WINDOW (window), NULL);
2540
2541 return GTK_WIDGET (priv->notebook);
2542}
2543
2544void
2545terminal_window_set_size (TerminalWindow *window,
2546 TerminalScreen *screen,
2547 gboolean even_if_mapped)
2548{
2549 terminal_window_set_size_force_grid (window, screen, even_if_mapped, -1, -1);
2550}
2551
2552void
2553terminal_window_set_size_force_grid (TerminalWindow *window,
2554 TerminalScreen *screen,
2555 gboolean even_if_mapped,
2556 int force_grid_width,
2557 int force_grid_height)
2558{
2559 /* Owen's hack from gnome-terminal */
2560 GtkWidget *widget;
2561 GtkWidget *app;
2562 GtkRequisition toplevel_request;
2563 GtkRequisition widget_request;
2564 int w, h;
2565 int char_width;
2566 int char_height;
2567 int grid_width;
2568 int grid_height;
2569 GtkBorder *inner_border = NULL;
2570
2571 /* be sure our geometry is up-to-date */
2572 terminal_window_update_geometry (window);
2573
2574 widget = GTK_WIDGET (screen);
2575
2576 app = gtk_widget_get_toplevel (widget);
2577 g_assert (app != NULL);
2578
2579 gtk_widget_size_request (app, &toplevel_request);
2580 gtk_widget_size_request (widget, &widget_request);
2581
2582 terminal_screen_get_cell_size (screen, &char_width, &char_height);
2583 terminal_screen_get_size (screen, &grid_width, &grid_height);
2584
2585 _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY,
2586 "[window %p] set size: toplevel %dx%d widget %dx%d grid %dx%d char-cell %dx%d\n",
2587 window,
2588 toplevel_request.width, toplevel_request.height,
2589 widget_request.width, widget_request.height,
2590 grid_width, grid_height, char_width, char_height);
2591
2592 w = toplevel_request.width - widget_request.width;
2593 h = toplevel_request.height - widget_request.height;
2594
2595 if (force_grid_width >= 0)
2596 grid_width = force_grid_width;
2597 if (force_grid_height >= 0)
2598 grid_height = force_grid_height;
2599
2600 gtk_widget_style_get (widget, "inner-border", &inner_border, NULL);
2601 w += (inner_border ? (inner_border->left + inner_border->right) : 0) + char_width * grid_width;
2602 h += (inner_border ? (inner_border->top + inner_border->bottom) : 0) + char_height * grid_height;
2603 gtk_border_free (inner_border);
2604
2605 _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY,
2606 "[window %p] set size: grid %dx%d force %dx%d setting %dx%d pixels\n",
2607 window,
2608 grid_width, grid_height, force_grid_width, force_grid_height, w, h);
2609
2610 if (even_if_mapped && gtk_widget_get_mapped (app)) {
2611 gtk_window_resize (GTK_WINDOW (app), w, h);
2612 }
2613 else {
2614 gtk_window_set_default_size (GTK_WINDOW (app), w, h);
2615 }
2616}
2617
2618void
2619terminal_window_switch_screen (TerminalWindow *window,
2620 TerminalScreen *screen)
2621{
2622 TerminalWindowPrivate *priv = window->priv;
2623 TerminalScreenContainer *screen_container;
2624 int page_num;
2625
2626 screen_container = terminal_screen_container_get_from_screen (screen);
2627 g_assert (TERMINAL_IS_SCREEN_CONTAINER (screen_container));
2628 page_num = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook),
2629 GTK_WIDGET (screen_container));
2630 gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), page_num);
2631}
2632
2633TerminalScreen*
2634terminal_window_get_active (TerminalWindow *window)
2635{
2636 TerminalWindowPrivate *priv = window->priv;
2637
2638 return priv->active_screen;
2639}
2640
2641static gboolean
2642notebook_button_press_cb (GtkWidget *widget,
2643 GdkEventButton *event,
2644 TerminalWindow *window)
2645{
2646 TerminalWindowPrivate *priv = window->priv;
2647 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2648 GtkWidget *menu;
2649 GtkAction *action;
2650 int tab_clicked;
2651
2652 if (event->type != GDK_BUTTON_PRESS ||
2653 event->button != 3 ||
2654 (event->state & gtk_accelerator_get_default_mod_mask ()) != 0)
2655 return FALSE;
2656
2657 tab_clicked = find_tab_num_at_pos (notebook, event->x_root, event->y_root);
2658 if (tab_clicked < 0)
2659 return FALSE;
2660
2661 /* switch to the page the mouse is over */
2662 gtk_notebook_set_current_page (notebook, tab_clicked);
2663
2664 action = gtk_action_group_get_action (priv->action_group, "NotebookPopup");
2665 gtk_action_activate (action);
2666
2667 menu = gtk_ui_manager_get_widget (priv->ui_manager, "/NotebookPopup");
2668 gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
2669 NULL, NULL,
2670 event->button, event->time);
2671
2672 return TRUE;
2673}
2674
2675static gboolean
2676notebook_popup_menu_cb (GtkWidget *widget,
2677 TerminalWindow *window)
2678{
2679 TerminalWindowPrivate *priv = window->priv;
2680 GtkNotebook *notebook = GTK_NOTEBOOK (priv->notebook);
2681 GtkWidget *focus_widget, *tab, *tab_label, *menu;
2682 GtkAction *action;
2683 int page_num;
2684
2685 focus_widget = gtk_window_get_focus (GTK_WINDOW (window));
2686 /* Only respond if the notebook is the actual focus */
2687 if (focus_widget != priv->notebook)
2688 return FALSE;
2689
2690 page_num = gtk_notebook_get_current_page (notebook);
2691 tab = gtk_notebook_get_nth_page (notebook, page_num);
2692 tab_label = gtk_notebook_get_tab_label (notebook, tab);
2693
2694 action = gtk_action_group_get_action (priv->action_group, "NotebookPopup");
2695 gtk_action_activate (action);
2696
2697 menu = gtk_ui_manager_get_widget (priv->ui_manager, "/NotebookPopup");
2698 gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
2699 position_menu_under_widget, tab_label,
2700 0, gtk_get_current_event_time ());
2701 gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE);
2702
2703 return TRUE;
2704}
2705
2706static void
2707notebook_page_selected_callback (GtkWidget *notebook,
2708#if GTK_CHECK_VERSION (2, 90, 6)
2709 GtkWidget *page_widget,
2710#else
2711 gpointer useless_crap,
2712#endif
2713 guint page_num,
2714 TerminalWindow *window)
2715{
2716 TerminalWindowPrivate *priv = window->priv;
2717 GtkWidget *widget;
2718 TerminalScreen *screen;
2719 TerminalProfile *profile;
2720 int old_grid_width, old_grid_height;
2721#if !GTK_CHECK_VERSION (2, 90, 6)
2722 GtkWidget *page_widget;
2723#endif
2724
2725 _terminal_debug_print (TERMINAL_DEBUG_MDI,
2726 "[window %p] MDI: page-selected %d\n",
2727 window, page_num);
2728
2729 if (priv->disposed)
2730 return;
2731
2732#if !GTK_CHECK_VERSION (2, 90, 6)
2733 page_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), page_num);
2734#endif
2735
2736 screen = terminal_screen_container_get_screen (TERMINAL_SCREEN_CONTAINER (page_widget));
2737 widget = GTK_WIDGET (screen);
2738 g_assert (screen != NULL);
2739
2740 _terminal_debug_print (TERMINAL_DEBUG_MDI,
2741 "[window %p] MDI: setting active tab to screen %p (old active screen %p)\n",
2742 window, screen, priv->active_screen);
2743
2744 if (priv->active_screen == screen)
2745 return;
2746
2747 if (priv->active_screen != NULL) {
2748 terminal_screen_get_size (priv->active_screen, &old_grid_width, &old_grid_height);
2749
2750 /* This is so that we maintain the same grid */
2751 vte_terminal_set_size (VTE_TERMINAL (screen), old_grid_width, old_grid_height);
2752 }
2753
2754 /* Workaround to remove gtknotebook's feature of computing its size based on
2755 * all pages. When the widget is hidden, its size will not be taken into
2756 * account.
2757 */
2758 if (priv->active_screen)
2759 gtk_widget_hide (GTK_WIDGET (priv->active_screen)); /* FIXME */
2760
2761 /* Make sure that the widget is no longer hidden due to the workaround */
2762 gtk_widget_show (widget);
2763
2764 profile = terminal_screen_get_profile (screen);
2765
2766 priv->active_screen = screen;
2767
2768 /* Override menubar setting if it wasn't restored from session */
2769 if (priv->use_default_menubar_visibility)
2770 {
2771 gboolean setting =
2772 terminal_profile_get_property_boolean (terminal_screen_get_profile (screen), TERMINAL_PROFILE_DEFAULT_SHOW_MENUBAR);
2773
2774 terminal_window_set_menubar_visible (window, setting);
2775 }
2776
2777 sync_screen_icon_title_set (screen, NULL, window);
2778 sync_screen_icon_title (screen, NULL, window);
2779 sync_screen_title (screen, NULL, window);
2780
2781 /* set size of window to current grid size */
2782 _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY,
2783 "[window %p] setting size after flipping notebook pages\n",
2784 window);
2785 terminal_window_set_size (window, screen, TRUE);
2786
2787 terminal_window_update_tabs_menu_sensitivity (window);
2788 terminal_window_update_encoding_menu_active_encoding (window);
2789 terminal_window_update_set_profile_menu_active_profile (window);
2790 terminal_window_update_copy_sensitivity (screen, window);
2791 terminal_window_update_zoom_sensitivity (window);
2792 terminal_window_update_search_sensitivity (screen, window);
2793}
2794
2795static void
2796notebook_page_added_callback (GtkWidget *notebook,
2797 GtkWidget *container,
2798 guint page_num,
2799 TerminalWindow *window)
2800{
2801 TerminalWindowPrivate *priv = window->priv;
2802 TerminalScreen *screen;
2803
2804 screen = terminal_screen_container_get_screen (TERMINAL_SCREEN_CONTAINER (container));
2805
2806 _terminal_debug_print (TERMINAL_DEBUG_MDI,
2807 "[window %p] MDI: screen %p inserted\n",
2808 window, screen);
2809
2810 g_signal_connect (G_OBJECT (screen),
2811 "profile-set",
2812 G_CALLBACK (profile_set_callback),
2813 window);
2814
2815 /* FIXME: only connect on the active screen, not all screens! */
2816 g_signal_connect (screen, "notify::title",
2817 G_CALLBACK (sync_screen_title), window);
2818 g_signal_connect (screen, "notify::icon-title",
2819 G_CALLBACK (sync_screen_icon_title), window);
2820 g_signal_connect (screen, "notify::icon-title-set",
2821 G_CALLBACK (sync_screen_icon_title_set), window);
2822 g_signal_connect (screen, "selection-changed",
2823 G_CALLBACK (terminal_window_update_copy_sensitivity), window);
2824
2825 g_signal_connect (screen, "show-popup-menu",
2826 G_CALLBACK (screen_show_popup_menu_callback), window);
2827 g_signal_connect (screen, "match-clicked",
2828 G_CALLBACK (screen_match_clicked_cb), window);
2829 g_signal_connect (screen, "resize-window",
2830 G_CALLBACK (screen_resize_window_cb), window);
2831
2832 g_signal_connect (screen, "close-screen",
2833 G_CALLBACK (screen_close_cb), window);
2834
2835 update_tab_visibility (window, 0);
2836 terminal_window_update_tabs_menu_sensitivity (window);
2837 terminal_window_update_search_sensitivity (screen, window);
2838
2839#if 0
2840 /* FIXMEchpe: wtf is this doing? */
2841
2842 /* If we have an active screen, match its size and zoom */
2843 if (priv->active_screen)
2844 {
2845 int current_width, current_height;
2846 double scale;
2847
2848 terminal_screen_get_size (priv->active_screen, &current_width, &current_height);
2849 vte_terminal_set_size (VTE_TERMINAL (screen), current_width, current_height);
2850
2851 scale = terminal_screen_get_font_scale (priv->active_screen);
2852 terminal_screen_set_font_scale (screen, scale);
2853 }
2854#endif
2855
2856 if (priv->present_on_insert)
2857 {
2858 gtk_window_present_with_time (GTK_WINDOW (window), gtk_get_current_event_time ());
2859 priv->present_on_insert = FALSE;
2860 }
2861}
2862
2863static void
2864notebook_page_removed_callback (GtkWidget *notebook,
2865 GtkWidget *container,
2866 guint page_num,
2867 TerminalWindow *window)
2868{
2869 TerminalWindowPrivate *priv = window->priv;
2870 TerminalScreen *screen;
2871 int pages;
2872
2873 if (priv->disposed)
2874 return;
2875
2876 screen = terminal_screen_container_get_screen (TERMINAL_SCREEN_CONTAINER (container));
2877
2878 _terminal_debug_print (TERMINAL_DEBUG_MDI,
2879 "[window %p] MDI: screen %p removed\n",
2880 window, screen);
2881
2882 g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
2883 G_CALLBACK (profile_set_callback),
2884 window);
2885
2886 g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
2887 G_CALLBACK (sync_screen_title),
2888 window);
2889
2890 g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
2891 G_CALLBACK (sync_screen_icon_title),
2892 window);
2893
2894 g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
2895 G_CALLBACK (sync_screen_icon_title_set),
2896 window);
2897
2898 g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
2899 G_CALLBACK (terminal_window_update_copy_sensitivity),
2900 window);
2901
2902 g_signal_handlers_disconnect_by_func (screen,
2903 G_CALLBACK (screen_show_popup_menu_callback),
2904 window);
2905
2906 g_signal_handlers_disconnect_by_func (screen,
2907 G_CALLBACK (screen_match_clicked_cb),
2908 window);
2909 g_signal_handlers_disconnect_by_func (screen,
2910 G_CALLBACK (screen_resize_window_cb),
2911 window);
2912
2913 g_signal_handlers_disconnect_by_func (screen,
2914 G_CALLBACK (screen_close_cb),
2915 window);
2916
2917 terminal_window_update_tabs_menu_sensitivity (window);
2918 update_tab_visibility (window, 0);
2919 terminal_window_update_search_sensitivity (screen, window);
2920
2921 pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook));
2922 if (pages == 1)
2923 {
2924 terminal_window_set_size (window, priv->active_screen, TRUE);
2925 }
2926 else if (pages == 0)
2927 {
2928 gtk_widget_destroy (GTK_WIDGET (window));
2929 }
2930}
2931
2932void
2933terminal_window_update_geometry (TerminalWindow *window)
2934{
2935 TerminalWindowPrivate *priv = window->priv;
2936 GtkWidget *widget;
2937 GdkGeometry hints;
2938 int char_width;
2939 int char_height;
2940
2941 if (priv->active_screen == NULL)
2942 return;
2943
2944 widget = GTK_WIDGET (priv->active_screen);
2945
2946 /* We set geometry hints from the active term; best thing
2947 * I can think of to do. Other option would be to try to
2948 * get some kind of union of all hints from all terms in the
2949 * window, but that doesn't make too much sense.
2950 */
2951 terminal_screen_get_cell_size (priv->active_screen, &char_width, &char_height);
2952
2953 if (char_width != priv->old_char_width ||
2954 char_height != priv->old_char_height ||
2955 widget != (GtkWidget*) priv->old_geometry_widget)
2956 {
2957 GtkBorder *inner_border = NULL;
2958
2959 /* FIXME Since we're using xthickness/ythickness to compute
2960 * padding we need to change the hints when the theme changes.
2961 */
2962
2963 gtk_widget_style_get (widget, "inner-border", &inner_border, NULL);
2964
2965 hints.base_width = (inner_border ? (inner_border->left + inner_border->right) : 0);
2966 hints.base_height = (inner_border ? (inner_border->top + inner_border->bottom) : 0);
2967
2968 gtk_border_free (inner_border);
2969
2970#define MIN_WIDTH_CHARS 4
2971#define MIN_HEIGHT_CHARS 1
2972
2973 hints.width_inc = char_width;
2974 hints.height_inc = char_height;
2975
2976 /* min size is min size of just the geometry widget, remember. */
2977 hints.min_width = hints.base_width + hints.width_inc * MIN_WIDTH_CHARS;
2978 hints.min_height = hints.base_height + hints.height_inc * MIN_HEIGHT_CHARS;
2979
2980 gtk_window_set_geometry_hints (GTK_WINDOW (window),
2981 widget,
2982 &hints,
2983 GDK_HINT_RESIZE_INC |
2984 GDK_HINT_MIN_SIZE |
2985 GDK_HINT_BASE_SIZE);
2986
2987 _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY,
2988 "[window %p] hints: base %dx%d min %dx%d inc %d %d\n",
2989 window,
2990 hints.base_width,
2991 hints.base_height,
2992 hints.min_width,
2993 hints.min_height,
2994 hints.width_inc,
2995 hints.height_inc);
2996
2997 priv->old_char_width = hints.width_inc;
2998 priv->old_char_height = hints.height_inc;
2999 priv->old_geometry_widget = widget;
3000 }
3001 else
3002 {
3003 _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY,
3004 "[window %p] hints: increment unchanged, not setting\n",
3005 window);
3006 }
3007}
3008
3009static void
3010file_new_window_callback (GtkAction *action,
3011 TerminalWindow *window)
3012{
3013 TerminalWindowPrivate *priv = window->priv;
3014 TerminalApp *app;
3015 TerminalWindow *new_window;
3016 TerminalProfile *profile;
3017 char *new_working_directory;
3018
3019 app = terminal_app_get ();
3020
3021 profile = g_object_get_data (G_OBJECT (action), PROFILE_DATA_KEY);
3022 if (!profile)
3023 profile = terminal_screen_get_profile (priv->active_screen);
3024 if (!profile)
3025 profile = terminal_app_get_profile_for_new_term (app);
3026 if (!profile)
3027 return;
3028
3029 if (_terminal_profile_get_forgotten (profile))
3030 return;
3031
3032 new_window = terminal_app_new_window (app, gtk_widget_get_screen (GTK_WIDGET (window)));
3033
3034 new_working_directory = terminal_screen_get_current_dir_with_fallback (priv->active_screen);
3035 terminal_app_new_terminal (app, new_window, profile,
3036 NULL, NULL,
3037 new_working_directory,
3038 terminal_screen_get_initial_environment (priv->active_screen),
3039 1.0);
3040 g_free (new_working_directory);
3041
3042 gtk_window_present (GTK_WINDOW (new_window));
3043}
3044
3045static void
3046file_new_tab_callback (GtkAction *action,
3047 TerminalWindow *window)
3048{
3049 TerminalWindowPrivate *priv = window->priv;
3050 TerminalApp *app;
3051 TerminalProfile *profile;
3052 char *new_working_directory;
3053
3054 app = terminal_app_get ();
3055 profile = g_object_get_data (G_OBJECT (action), PROFILE_DATA_KEY);
3056 if (!profile)
3057 profile = terminal_screen_get_profile (priv->active_screen);
3058 if (!profile)
3059 profile = terminal_app_get_profile_for_new_term (app);
3060 if (!profile)
3061 return;
3062
3063 if (_terminal_profile_get_forgotten (profile))
3064 return;
3065
3066 new_working_directory = terminal_screen_get_current_dir_with_fallback (priv->active_screen);
3067 terminal_app_new_terminal (app, window, profile,
3068 NULL, NULL,
3069 new_working_directory,
3070 terminal_screen_get_initial_environment (priv->active_screen),
3071 1.0);
3072 g_free (new_working_directory);
3073}
3074
3075static void
3076confirm_close_response_cb (GtkWidget *dialog,
3077 int response,
3078 TerminalWindow *window)
3079{
3080 TerminalScreen *screen;
3081
3082 screen = g_object_get_data (G_OBJECT (dialog), "close-screen");
3083
3084 gtk_widget_destroy (dialog);
3085
3086 if (response != GTK_RESPONSE_ACCEPT)
3087 return;
3088
3089 if (screen)
3090 terminal_window_remove_screen (window, screen);
3091 else
3092 gtk_widget_destroy (GTK_WIDGET (window));
3093}
3094
3095/* Returns: TRUE if closing needs to wait until user confirmation;
3096 * FALSE if the terminal or window can close immediately.
3097 */
3098static gboolean
3099confirm_close_window_or_tab (TerminalWindow *window,
3100 TerminalScreen *screen)
3101{
3102 TerminalWindowPrivate *priv = window->priv;
3103 GtkWidget *dialog;
3104 GConfClient *client;
3105 gboolean do_confirm;
3106 int n_tabs;
3107
3108 if (priv->confirm_close_dialog)
3109 {
3110 /* WTF, already have one? It's modal, so how did that happen? */
3111 gtk_dialog_response (GTK_DIALOG (priv->confirm_close_dialog),
3112 GTK_RESPONSE_DELETE_EVENT);
3113 }
3114
3115 client = gconf_client_get_default ();
3116 do_confirm = gconf_client_get_bool (client, CONF_GLOBAL_PREFIX "/confirm_window_close", NULL);
3117 g_object_unref (client);
3118 if (!do_confirm)
3119 return FALSE;
3120
3121 if (screen)
3122 {
3123 do_confirm = terminal_screen_has_foreground_process (screen);
3124 n_tabs = 1;
3125 }
3126 else
3127 {
3128 GList *tabs, *t;
3129
3130 do_confirm = FALSE;
3131
3132 tabs = terminal_window_list_screen_containers (window);
3133 n_tabs = g_list_length (tabs);
3134
3135 for (t = tabs; t != NULL; t = t->next)
3136 {
3137 TerminalScreen *terminal_screen;
3138
3139 terminal_screen = terminal_screen_container_get_screen (TERMINAL_SCREEN_CONTAINER (t->data));
3140 if (terminal_screen_has_foreground_process (terminal_screen))
3141 {
3142 do_confirm = TRUE;
3143 break;
3144 }
3145 }
3146 g_list_free (tabs);
3147 }
3148
3149 if (!do_confirm)
3150 return FALSE;
3151
3152 dialog = priv->confirm_close_dialog =
3153 gtk_message_dialog_new (GTK_WINDOW (window),
3154 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
3155 GTK_MESSAGE_WARNING,
3156 GTK_BUTTONS_CANCEL,
3157 "%s", n_tabs > 1 ? _("Close this window?") : _("Close this terminal?"));
3158
3159 if (n_tabs > 1)
3160 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
3161 "%s", _("There are still processes running in some terminals in this window. "
3162 "Closing the window will kill all of them."));
3163 else
3164 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
3165 "%s", _("There is still a process running in this terminal. "
3166 "Closing the terminal will kill it."));
3167
3168 gtk_window_set_title (GTK_WINDOW (dialog), "");
3169
3170 gtk_dialog_add_button (GTK_DIALOG (dialog), n_tabs > 1 ? _("C_lose Window") : _("C_lose Terminal"), GTK_RESPONSE_ACCEPT);
3171 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
3172
3173 gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
3174 GTK_RESPONSE_ACCEPT,
3175 GTK_RESPONSE_CANCEL,
3176 -1);
3177
3178 g_object_set_data (G_OBJECT (dialog), "close-screen", screen);
3179
3180 g_signal_connect (dialog, "destroy",
3181 G_CALLBACK (gtk_widget_destroyed), &priv->confirm_close_dialog);
3182 g_signal_connect (dialog, "response",
3183 G_CALLBACK (confirm_close_response_cb), window);
3184
3185 gtk_window_present (GTK_WINDOW (dialog));
3186
3187 return TRUE;
3188}
3189
3190static void
3191file_close_window_callback (GtkAction *action,
3192 TerminalWindow *window)
3193{
3194 if (confirm_close_window_or_tab (window, NULL))
3195 return;
3196
3197 gtk_widget_destroy (GTK_WIDGET (window));
3198}
3199
3200#ifdef ENABLE_SAVE
3201static void
3202save_contents_dialog_on_response (GtkDialog *dialog, gint response_id, gpointer terminal)
3203{
3204 GtkWindow *parent;
3205 gchar *filename_uri = NULL;
3206 GFile *file;
3207 GOutputStream *stream;
3208 GError *error = NULL;
3209
3210 if (response_id != GTK_RESPONSE_ACCEPT)
3211 {
3212 gtk_widget_destroy (GTK_WIDGET (dialog));
3213 return;
3214 }
3215
3216 parent = (GtkWindow*) gtk_widget_get_ancestor (GTK_WIDGET (terminal), GTK_TYPE_WINDOW);
3217 filename_uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
3218
3219 gtk_widget_destroy (GTK_WIDGET (dialog));
3220
3221 if (filename_uri == NULL)
3222 return;
3223
3224 file = g_file_new_for_uri (filename_uri);
3225 stream = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error));
3226
3227 if (stream)
3228 {
3229 /* XXX
3230 * FIXME
3231 * This is a sync operation.
3232 * Should be replaced with the async version when vte implements that.
3233 */
3234 vte_terminal_write_contents (terminal, stream,
3235 VTE_TERMINAL_WRITE_DEFAULT,
3236 NULL, &error);
3237 g_object_unref (stream);
3238 }
3239
3240 if (error)
3241 {
3242 terminal_util_show_error_dialog (parent, NULL, error,
3243 "%s", _("Could not save contents"));
3244 g_error_free (error);
3245 }
3246
3247 g_object_unref(file);
3248 g_free(filename_uri);
3249}
3250#endif /* ENABLE_SAVE */
3251
3252static void
3253file_save_contents_callback (GtkAction *action,
3254 TerminalWindow *window)
3255{
3256#ifdef ENABLE_SAVE
3257 GtkWidget *dialog = NULL;
3258 TerminalWindowPrivate *priv = window->priv;
3259 VteTerminal *terminal;
3260
3261 if (!priv->active_screen)
3262 return;
3263
3264 terminal = VTE_TERMINAL (priv->active_screen);
3265 g_return_if_fail (VTE_IS_TERMINAL (terminal));
3266
3267 dialog = gtk_file_chooser_dialog_new (_("Save as..."),
3268 GTK_WINDOW(window),
3269 GTK_FILE_CHOOSER_ACTION_SAVE,
3270 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
3271 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
3272 NULL);
3273
3274 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
3275 /* XXX where should we save to? */
3276 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP));
3277
3278 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW(window));
3279 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3280 gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
3281
3282 g_signal_connect (dialog, "response", G_CALLBACK (save_contents_dialog_on_response), terminal);
3283 g_signal_connect (dialog, "delete_event", G_CALLBACK (terminal_util_dialog_response_on_delete), NULL);
3284
3285 gtk_window_present (GTK_WINDOW (dialog));
3286#endif /* ENABLE_SAVE */
3287}
3288
3289static void
3290file_close_tab_callback (GtkAction *action,
3291 TerminalWindow *window)
3292{
3293 TerminalWindowPrivate *priv = window->priv;
3294 TerminalScreen *active_screen = priv->active_screen;
3295
3296 if (!active_screen)
3297 return;
3298
3299 if (confirm_close_window_or_tab (window, active_screen))
3300 return;
3301
3302 terminal_window_remove_screen (window, active_screen);
3303}
3304
3305static void
3306edit_copy_callback (GtkAction *action,
3307 TerminalWindow *window)
3308{
3309 TerminalWindowPrivate *priv = window->priv;
3310
3311 if (!priv->active_screen)
3312 return;
3313
3314 vte_terminal_copy_clipboard (VTE_TERMINAL (priv->active_screen));
3315}
3316
3317typedef struct {
3318 TerminalScreen *screen;
3319 gboolean uris_as_paths;
3320} PasteData;
3321
3322static void
3323clipboard_uris_received_cb (GtkClipboard *clipboard,
3324 /* const */ char **uris,
3325 PasteData *data)
3326{
3327 char *text;
3328 gsize len;
3329
3330 if (!uris) {
3331 g_object_unref (data->screen);
3332 g_slice_free (PasteData, data);
3333 return;
3334 }
3335
3336 /* This potentially modifies the strings in |uris| but that's ok */
3337 if (data->uris_as_paths)
3338 terminal_util_transform_uris_to_quoted_fuse_paths (uris);
3339
3340 text = terminal_util_concat_uris (uris, &len);
3341 vte_terminal_feed_child (VTE_TERMINAL (data->screen), text, len);
3342 g_free (text);
3343
3344 g_object_unref (data->screen);
3345 g_slice_free (PasteData, data);
3346}
3347
3348static void
3349clipboard_targets_received_cb (GtkClipboard *clipboard,
3350 GdkAtom *targets,
3351 int n_targets,
3352 PasteData *data)
3353{
3354 if (!targets) {
3355 g_object_unref (data->screen);
3356 g_slice_free (PasteData, data);
3357 return;
3358 }
3359
3360 if (gtk_targets_include_uri (targets, n_targets)) {
3361 gtk_clipboard_request_uris (clipboard,
3362 (GtkClipboardURIReceivedFunc) clipboard_uris_received_cb,
3363 data);
3364 return;
3365 } else /* if (gtk_targets_include_text (targets, n_targets)) */ {
3366 vte_terminal_paste_clipboard (VTE_TERMINAL (data->screen));
3367 }
3368
3369 g_object_unref (data->screen);
3370 g_slice_free (PasteData, data);
3371}
3372
3373static void
3374edit_paste_callback (GtkAction *action,
3375 TerminalWindow *window)
3376{
3377 TerminalWindowPrivate *priv = window->priv;
3378 GtkClipboard *clipboard;
3379 PasteData *data;
3380 const char *name;
3381
3382 if (!priv->active_screen)
3383 return;
3384
3385 clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), GDK_SELECTION_CLIPBOARD);
3386 name = gtk_action_get_name (action);
3387
3388 data = g_slice_new (PasteData);
3389 data->screen = g_object_ref (priv->active_screen);
3390 data->uris_as_paths = (name == I_("EditPasteURIPaths") || name == I_("PopupPasteURIPaths"));
3391
3392 gtk_clipboard_request_targets (clipboard,
3393 (GtkClipboardTargetsReceivedFunc) clipboard_targets_received_cb,
3394 data);
3395}
3396
3397static void
3398edit_select_all_callback (GtkAction *action,
3399 TerminalWindow *window)
3400{
3401 TerminalWindowPrivate *priv = window->priv;
3402
3403 if (!priv->active_screen)
3404 return;
3405
3406 vte_terminal_select_all (VTE_TERMINAL (priv->active_screen));
3407}
3408
3409static void
3410edit_keybindings_callback (GtkAction *action,
3411 TerminalWindow *window)
3412{
3413 terminal_app_edit_keybindings (terminal_app_get (),
3414 GTK_WINDOW (window));
3415}
3416
3417static void
3418edit_current_profile_callback (GtkAction *action,
3419 TerminalWindow *window)
3420{
3421 TerminalWindowPrivate *priv = window->priv;
3422
3423 terminal_app_edit_profile (terminal_app_get (),
3424 terminal_screen_get_profile (priv->active_screen),
3425 GTK_WINDOW (window),
3426 NULL);
3427}
3428
3429static void
3430file_new_profile_callback (GtkAction *action,
3431 TerminalWindow *window)
3432{
3433 TerminalWindowPrivate *priv = window->priv;
3434
3435 terminal_app_new_profile (terminal_app_get (),
3436 terminal_screen_get_profile (priv->active_screen),
3437 GTK_WINDOW (window));
3438}
3439
3440static void
3441edit_profiles_callback (GtkAction *action,
3442 TerminalWindow *window)
3443{
3444 terminal_app_manage_profiles (terminal_app_get (),
3445 GTK_WINDOW (window));
3446}
3447
3448static void
3449view_menubar_toggled_callback (GtkToggleAction *action,
3450 TerminalWindow *window)
3451{
3452 terminal_window_set_menubar_visible (window, gtk_toggle_action_get_active (action));
3453}
3454
3455static void
3456view_fullscreen_toggled_callback (GtkToggleAction *action,
3457 TerminalWindow *window)
3458{
3459 g_return_if_fail (gtk_widget_get_realized (GTK_WIDGET (window)));
3460
3461 if (gtk_toggle_action_get_active (action))
3462 gtk_window_fullscreen (GTK_WINDOW (window));
3463 else
3464 gtk_window_unfullscreen (GTK_WINDOW (window));
3465}
3466
3467static const double zoom_factors[] = {
3468 TERMINAL_SCALE_MINIMUM,
3469 TERMINAL_SCALE_XXXXX_SMALL,
3470 TERMINAL_SCALE_XXXX_SMALL,
3471 TERMINAL_SCALE_XXX_SMALL,
3472 PANGO_SCALE_XX_SMALL,
3473 PANGO_SCALE_X_SMALL,
3474 PANGO_SCALE_SMALL,
3475 PANGO_SCALE_MEDIUM,
3476 PANGO_SCALE_LARGE,
3477 PANGO_SCALE_X_LARGE,
3478 PANGO_SCALE_XX_LARGE,
3479 TERMINAL_SCALE_XXX_LARGE,
3480 TERMINAL_SCALE_XXXX_LARGE,
3481 TERMINAL_SCALE_XXXXX_LARGE,
3482 TERMINAL_SCALE_MAXIMUM
3483};
3484
3485static gboolean
3486find_larger_zoom_factor (double current,
3487 double *found)
3488{
3489 guint i;
3490
3491 for (i = 0; i < G_N_ELEMENTS (zoom_factors); ++i)
3492 {
3493 /* Find a font that's larger than this one */
3494 if ((zoom_factors[i] - current) > 1e-6)
3495 {
3496 *found = zoom_factors[i];
3497 return TRUE;
3498 }
3499 }
3500
3501 return FALSE;
3502}
3503
3504static gboolean
3505find_smaller_zoom_factor (double current,
3506 double *found)
3507{
3508 int i;
3509
3510 i = (int) G_N_ELEMENTS (zoom_factors) - 1;
3511 while (i >= 0)
3512 {
3513 /* Find a font that's smaller than this one */
3514 if ((current - zoom_factors[i]) > 1e-6)
3515 {
3516 *found = zoom_factors[i];
3517 return TRUE;
3518 }
3519
3520 --i;
3521 }
3522
3523 return FALSE;
3524}
3525
3526static void
3527view_zoom_in_callback (GtkAction *action,
3528 TerminalWindow *window)
3529{
3530 TerminalWindowPrivate *priv = window->priv;
3531 double current;
3532
3533 if (priv->active_screen == NULL)
3534 return;
3535
3536 current = terminal_screen_get_font_scale (priv->active_screen);
3537 if (!find_larger_zoom_factor (current, &current))
3538 return;
3539
3540 terminal_screen_set_font_scale (priv->active_screen, current);
3541 terminal_window_update_zoom_sensitivity (window);
3542}
3543
3544static void
3545view_zoom_out_callback (GtkAction *action,
3546 TerminalWindow *window)
3547{
3548 TerminalWindowPrivate *priv = window->priv;
3549 double current;
3550
3551 if (priv->active_screen == NULL)
3552 return;
3553
3554 current = terminal_screen_get_font_scale (priv->active_screen);
3555 if (!find_smaller_zoom_factor (current, &current))
3556 return;
3557
3558 terminal_screen_set_font_scale (priv->active_screen, current);
3559 terminal_window_update_zoom_sensitivity (window);
3560}
3561
3562static void
3563view_zoom_normal_callback (GtkAction *action,
3564 TerminalWindow *window)
3565{
3566 TerminalWindowPrivate *priv = window->priv;
3567
3568 if (priv->active_screen == NULL)
3569 return;
3570
3571 terminal_screen_set_font_scale (priv->active_screen, PANGO_SCALE_MEDIUM);
3572 terminal_window_update_zoom_sensitivity (window);
3573}
3574
3575
3576static void
3577search_find_response_callback (GtkWidget *dialog,
3578 int response,
3579 gpointer user_data)
3580{
3581 TerminalWindow *window = TERMINAL_WINDOW (user_data);
3582 TerminalWindowPrivate *priv = window->priv;
3583 TerminalSearchFlags flags;
3584 GRegex *regex;
3585
3586 if (response != GTK_RESPONSE_ACCEPT)
3587 return;
3588
3589 if (G_UNLIKELY (!priv->active_screen))
3590 return;
3591
3592 regex = terminal_search_dialog_get_regex (dialog);
3593 g_return_if_fail (regex != NULL);
3594
3595 flags = terminal_search_dialog_get_search_flags (dialog);
3596
3597 vte_terminal_search_set_gregex (VTE_TERMINAL (priv->active_screen), regex);
3598 vte_terminal_search_set_wrap_around (VTE_TERMINAL (priv->active_screen),
3599 (flags & TERMINAL_SEARCH_FLAG_WRAP_AROUND));
3600
3601 if (flags & TERMINAL_SEARCH_FLAG_BACKWARDS)
3602 vte_terminal_search_find_previous (VTE_TERMINAL (priv->active_screen));
3603 else
3604 vte_terminal_search_find_next (VTE_TERMINAL (priv->active_screen));
3605
3606 terminal_window_update_search_sensitivity (priv->active_screen, window);
3607}
3608
3609static gboolean
3610search_dialog_delete_event_cb (GtkWidget *widget,
3611 GdkEventAny *event,
3612 gpointer user_data)
3613{
3614 /* prevent destruction */
3615 return TRUE;
3616}
3617
3618static void
3619search_find_callback (GtkAction *action,
3620 TerminalWindow *window)
3621{
3622 TerminalWindowPrivate *priv = window->priv;
3623
3624 if (!priv->search_find_dialog) {
3625 GtkWidget *dialog;
3626
3627 dialog = priv->search_find_dialog = terminal_search_dialog_new (GTK_WINDOW (window));
3628
3629 g_signal_connect (dialog, "destroy",
3630 G_CALLBACK (gtk_widget_destroyed), &priv->search_find_dialog);
3631 g_signal_connect (dialog, "response",
3632 G_CALLBACK (search_find_response_callback), window);
3633 g_signal_connect (dialog, "delete-event",
3634 G_CALLBACK (search_dialog_delete_event_cb), NULL);
3635 }
3636
3637 terminal_search_dialog_present (priv->search_find_dialog);
3638}
3639
3640static void
3641search_find_next_callback (GtkAction *action,
3642 TerminalWindow *window)
3643{
3644 if (G_UNLIKELY (!window->priv->active_screen))
3645 return;
3646
3647 vte_terminal_search_find_next (VTE_TERMINAL (window->priv->active_screen));
3648}
3649
3650static void
3651search_find_prev_callback (GtkAction *action,
3652 TerminalWindow *window)
3653{
3654 if (G_UNLIKELY (!window->priv->active_screen))
3655 return;
3656
3657 vte_terminal_search_find_previous (VTE_TERMINAL (window->priv->active_screen));
3658}
3659
3660static void
3661search_clear_highlight_callback (GtkAction *action,
3662 TerminalWindow *window)
3663{
3664 if (G_UNLIKELY (!window->priv->active_screen))
3665 return;
3666
3667 vte_terminal_search_set_gregex (VTE_TERMINAL (window->priv->active_screen), NULL);
3668}
3669
3670static void
3671terminal_set_title_dialog_response_cb (GtkWidget *dialog,
3672 int response,
3673 TerminalScreen *screen)
3674{
3675 if (response == GTK_RESPONSE_OK)
3676 {
3677 GtkEntry *entry;
3678 const char *text;
3679
3680 entry = GTK_ENTRY (g_object_get_data (G_OBJECT (dialog), "title-entry"));
3681 text = gtk_entry_get_text (entry);
3682 terminal_screen_set_user_title (screen, text);
3683 }
3684
3685 gtk_widget_destroy (dialog);
3686}
3687
3688static void
3689terminal_set_title_callback (GtkAction *action,
3690 TerminalWindow *window)
3691{
3692 TerminalWindowPrivate *priv = window->priv;
3693 GtkWidget *dialog, *message_area, *hbox, *label, *entry;
3694
3695 if (priv->active_screen == NULL)
3696 return;
3697
3698 /* FIXME: hook the screen up so this dialogue closes if the terminal screen closes */
3699
3700 dialog = gtk_message_dialog_new (GTK_WINDOW (window),
3701 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
3702 GTK_MESSAGE_OTHER,
3703 GTK_BUTTONS_OK_CANCEL,
3704 "%s", "");
3705
3706 gtk_window_set_title (GTK_WINDOW (dialog), _("Set Title"));
3707 gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
3708 gtk_window_set_role (GTK_WINDOW (dialog), "gnome-terminal-change-title");
3709 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
3710 /* Alternative button order was set automatically by GtkMessageDialog */
3711
3712 g_signal_connect (dialog, "response",
3713 G_CALLBACK (terminal_set_title_dialog_response_cb), priv->active_screen);
3714 g_signal_connect (dialog, "delete-event",
3715 G_CALLBACK (terminal_util_dialog_response_on_delete), NULL);
3716
3717#if GTK_CHECK_VERSION (2, 90, 6)
3718 message_area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (dialog));
3719 gtk_container_foreach (GTK_CONTAINER (message_area), (GtkCallback) gtk_widget_hide, NULL);
3720#else
3721 label = GTK_MESSAGE_DIALOG (dialog)->label;
3722 gtk_widget_hide (label);
3723 message_area = gtk_widget_get_parent (label);
3724#endif
3725
3726 hbox = gtk_hbox_new (FALSE, 12);
3727 gtk_box_pack_start (GTK_BOX (message_area), hbox, FALSE, FALSE, 0);
3728
3729 label = gtk_label_new_with_mnemonic (_("_Title:"));
3730 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3731 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
3732
3733 entry = gtk_entry_new ();
3734 gtk_entry_set_width_chars (GTK_ENTRY (entry), 32);
3735 gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
3736 gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
3737 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
3738 gtk_widget_show_all (hbox);
3739
3740 gtk_widget_grab_focus (entry);
3741 gtk_entry_set_text (GTK_ENTRY (entry), terminal_screen_get_raw_title (priv->active_screen));
3742 gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
3743 g_object_set_data (G_OBJECT (dialog), "title-entry", entry);
3744
3745 gtk_window_present (GTK_WINDOW (dialog));
3746}
3747
3748static void
3749terminal_add_encoding_callback (GtkAction *action,
3750 TerminalWindow *window)
3751{
3752 terminal_app_edit_encodings (terminal_app_get (),
3753 GTK_WINDOW (window));
3754}
3755
3756static void
3757terminal_reset_callback (GtkAction *action,
3758 TerminalWindow *window)
3759{
3760 TerminalWindowPrivate *priv = window->priv;
3761
3762 if (priv->active_screen == NULL)
3763 return;
3764
3765 vte_terminal_reset (VTE_TERMINAL (priv->active_screen), TRUE, FALSE);
3766}
3767
3768static void
3769terminal_reset_clear_callback (GtkAction *action,
3770 TerminalWindow *window)
3771{
3772 TerminalWindowPrivate *priv = window->priv;
3773
3774 if (priv->active_screen == NULL)
3775 return;
3776
3777 vte_terminal_reset (VTE_TERMINAL (priv->active_screen), TRUE, TRUE);
3778}
3779
3780static void
3781tabs_next_or_previous_tab_cb (GtkAction *action,
3782 TerminalWindow *window)
3783{
3784 TerminalWindowPrivate *priv = window->priv;
3785 GtkNotebookClass *klass;
3786 GtkBindingSet *binding_set;
3787 const char *name;
3788 guint keyval = 0;
3789
3790 name = gtk_action_get_name (action);
3791 if (strcmp (name, "TabsNext") == 0) {
3792 keyval = GDK_Page_Down;
3793 } else if (strcmp (name, "TabsPrevious") == 0) {
3794 keyval = GDK_Page_Up;
3795 }
3796
3797 klass = GTK_NOTEBOOK_GET_CLASS (GTK_NOTEBOOK (priv->notebook));
3798 binding_set = gtk_binding_set_by_class (klass);
3799 gtk_binding_set_activate (gtk_binding_set_by_class (klass),
3800 keyval,
3801 GDK_CONTROL_MASK,
3802 GTK_OBJECT (priv->notebook));
3803}
3804
3805static void
3806tabs_move_left_callback (GtkAction *action,
3807 TerminalWindow *window)
3808{
3809 TerminalWindowPrivate *priv = window->priv;
3810 GtkNotebook *notebook = GTK_NOTEBOOK (priv->notebook);
3811 gint page_num,last_page;
3812 GtkWidget *page;
3813
3814 page_num = gtk_notebook_get_current_page (notebook);
3815 last_page = gtk_notebook_get_n_pages (notebook) - 1;
3816 page = gtk_notebook_get_nth_page (notebook, page_num);
3817
3818 gtk_notebook_reorder_child (notebook, page, page_num == 0 ? last_page : page_num - 1);
3819}
3820
3821static void
3822tabs_move_right_callback (GtkAction *action,
3823 TerminalWindow *window)
3824{
3825 TerminalWindowPrivate *priv = window->priv;
3826 GtkNotebook *notebook = GTK_NOTEBOOK (priv->notebook);
3827 gint page_num,last_page;
3828 GtkWidget *page;
3829
3830 page_num = gtk_notebook_get_current_page (notebook);
3831 last_page = gtk_notebook_get_n_pages (notebook) - 1;
3832 page = gtk_notebook_get_nth_page (notebook, page_num);
3833
3834 gtk_notebook_reorder_child (notebook, page, page_num == last_page ? 0 : page_num + 1);
3835}
3836
3837static void
3838tabs_detach_tab_callback (GtkAction *action,
3839 TerminalWindow *window)
3840{
3841 TerminalWindowPrivate *priv = window->priv;
3842 TerminalApp *app;
3843 TerminalWindow *new_window;
3844 TerminalScreen *screen;
3845 char *geometry;
3846 int width, height;
3847
3848 app = terminal_app_get ();
3849
3850 screen = priv->active_screen;
3851
3852 /* FIXME: this seems wrong if tabs are shown in the window */
3853 terminal_screen_get_size (screen, &width, &height);
3854 geometry = g_strdup_printf ("%dx%d", width, height);
3855
3856 new_window = terminal_app_new_window (app, gtk_widget_get_screen (GTK_WIDGET (window)));
3857
3858 terminal_window_move_screen (window, new_window, screen, -1);
3859
3860 gtk_window_parse_geometry (GTK_WINDOW (new_window), geometry);
3861 g_free (geometry);
3862
3863 gtk_window_present_with_time (GTK_WINDOW (new_window), gtk_get_current_event_time ());
3864}
3865
3866static void
3867help_contents_callback (GtkAction *action,
3868 TerminalWindow *window)
3869{
3870 terminal_util_show_help (NULL, GTK_WINDOW (window));
3871}
3872
3873#define ABOUT_GROUP "About"
3874#define EMAILIFY(string) (g_strdelimit ((string), "%", '@'))
3875
3876static void
3877help_about_callback (GtkAction *action,
3878 TerminalWindow *window)
3879{
3880 static const char copyright[] =
3881 "Copyright © 2002–2004 Havoc Pennington\n"
3882 "Copyright © 2003–2004, 2007 Mariano Suárez-Alvarez\n"
3883 "Copyright © 2006 Guilherme de S. Pastore\n"
3884 "Copyright © 2007–2010 Christian Persch";
3885 char *licence_text;
3886 GKeyFile *key_file;
3887 GError *error = NULL;
3888 char **authors, **contributors, **artists, **documenters, **array_strv;
3889 gsize n_authors = 0, n_contributors = 0, n_artists = 0, n_documenters = 0 , i;
3890 GPtrArray *array;
3891
3892 key_file = g_key_file_new ();
3893 if (!g_key_file_load_from_file (key_file, TERM_PKGDATADIR G_DIR_SEPARATOR_S "terminal.about", 0, &error))
3894 {
3895 g_warning ("Couldn't load about data: %s\n", error->message);
3896 g_error_free (error);
3897 g_key_file_free (key_file);
3898 return;
3899 }
3900
3901 authors = g_key_file_get_string_list (key_file, ABOUT_GROUP, "Authors", &n_authors, NULL);
3902 contributors = g_key_file_get_string_list (key_file, ABOUT_GROUP, "Contributors", &n_contributors, NULL);
3903 artists = g_key_file_get_string_list (key_file, ABOUT_GROUP, "Artists", &n_artists, NULL);
3904 documenters = g_key_file_get_string_list (key_file, ABOUT_GROUP, "Documenters", &n_documenters, NULL);
3905 g_key_file_free (key_file);
3906
3907 array = g_ptr_array_new ();
3908
3909 for (i = 0; i < n_authors; ++i)
3910 g_ptr_array_add (array, EMAILIFY (authors[i]));
3911 g_free (authors); /* strings are now owned by the array */
3912
3913 if (n_contributors > 0)
3914 {
3915 g_ptr_array_add (array, g_strdup (""));
3916 g_ptr_array_add (array, g_strdup (_("Contributors:")));
3917 for (i = 0; i < n_contributors; ++i)
3918 g_ptr_array_add (array, EMAILIFY (contributors[i]));
3919 }
3920 g_free (contributors); /* strings are now owned by the array */
3921
3922 g_ptr_array_add (array, NULL);
3923 array_strv = (char **) g_ptr_array_free (array, FALSE);
3924
3925 for (i = 0; i < n_artists; ++i)
3926 artists[i] = EMAILIFY (artists[i]);
3927 for (i = 0; i < n_documenters; ++i)
3928 documenters[i] = EMAILIFY (documenters[i]);
3929
3930 licence_text = terminal_util_get_licence_text ();
3931
3932 gtk_show_about_dialog (GTK_WINDOW (window),
3933 "program-name", _("GNOME Terminal"),
3934 "copyright", copyright,
3935 "comments", _("A terminal emulator for the GNOME desktop"),
3936 "version", VERSION,
3937 "authors", array_strv,
3938 "artists", artists,
3939 "documenters", documenters,
3940 "license", licence_text,
3941 "wrap-license", TRUE,
3942 "translator-credits", _("translator-credits"),
3943 "logo-icon-name", GNOME_TERMINAL_ICON_NAME,
3944 NULL);
3945
3946 g_strfreev (array_strv);
3947 g_strfreev (artists);
3948 g_strfreev (documenters);
3949 g_free (licence_text);
3950}
3951
3952GtkUIManager *
3953terminal_window_get_ui_manager (TerminalWindow *window)
3954{
3955 TerminalWindowPrivate *priv = window->priv;
3956
3957 return priv->ui_manager;
3958}
3959
3960void
3961terminal_window_save_state (TerminalWindow *window,
3962 GKeyFile *key_file,
3963 const char *group)
3964{
3965 TerminalWindowPrivate *priv = window->priv;
3966 GList *tabs, *lt;
3967 TerminalScreen *active_screen;
3968 GdkWindowState state;
3969 GPtrArray *tab_names_array;
3970 char **tab_names;
3971 gsize len;
3972
3973 //XXXif (priv->menub)//XXX
3974 g_key_file_set_boolean (key_file, group, TERMINAL_CONFIG_WINDOW_PROP_MENUBAR_VISIBLE,
3975 priv->menubar_visible);
3976
3977 g_key_file_set_string (key_file, group, TERMINAL_CONFIG_WINDOW_PROP_ROLE,
3978 gtk_window_get_role (GTK_WINDOW (window)));
3979
3980 state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (window)));
3981 if (state & GDK_WINDOW_STATE_MAXIMIZED)
3982 g_key_file_set_boolean (key_file, group, TERMINAL_CONFIG_WINDOW_PROP_MAXIMIZED, TRUE);
3983 if (state & GDK_WINDOW_STATE_FULLSCREEN)
3984 g_key_file_set_boolean (key_file, group, TERMINAL_CONFIG_WINDOW_PROP_FULLSCREEN, TRUE);
3985
3986 active_screen = terminal_window_get_active (window);
3987 tabs = terminal_window_list_screen_containers (window);
3988
3989 tab_names_array = g_ptr_array_sized_new (g_list_length (tabs) + 1);
3990
3991 for (lt = tabs; lt != NULL; lt = lt->next)
3992 {
3993 TerminalScreen *screen;
3994 char *tab_group;
3995
3996 screen = terminal_screen_container_get_screen (TERMINAL_SCREEN_CONTAINER (lt->data));
3997
3998 tab_group = g_strdup_printf ("Terminal%p", screen);
3999 g_ptr_array_add (tab_names_array, tab_group);
4000
4001 terminal_screen_save_config (screen, key_file, tab_group);
4002
4003 if (screen == active_screen)
4004 {
4005 int w, h, x, y;
4006 char *geometry;
4007
4008 g_key_file_set_string (key_file, group, TERMINAL_CONFIG_WINDOW_PROP_ACTIVE_TAB, tab_group);
4009
4010 /* FIXME saving the geometry is not great :-/ */
4011 terminal_screen_get_size (screen, &w, &h);
4012 gtk_window_get_position (GTK_WINDOW (window), &x, &y);
4013 geometry = g_strdup_printf ("%dx%d+%d+%d", w, h, x, y);
4014 g_key_file_set_string (key_file, group, TERMINAL_CONFIG_WINDOW_PROP_GEOMETRY, geometry);
4015 g_free (geometry);
4016 }
4017 }
4018
4019 g_list_free (tabs);
4020
4021 len = tab_names_array->len;
4022 g_ptr_array_add (tab_names_array, NULL);
4023 tab_names = (char **) g_ptr_array_free (tab_names_array, FALSE);
4024 g_key_file_set_string_list (key_file, group, TERMINAL_CONFIG_WINDOW_PROP_TABS, (const char * const *) tab_names, len);
4025 g_strfreev (tab_names);
4026}
04027
=== added file '.pc/01_lpi.patch/src/terminal.xml'
--- .pc/01_lpi.patch/src/terminal.xml 1970-01-01 00:00:00 +0000
+++ .pc/01_lpi.patch/src/terminal.xml 2011-05-27 08:11:08 +0000
@@ -0,0 +1,116 @@
1<ui>
2 <menubar>
3 <menu action="File">
4 <menuitem action="FileNewWindow" />
5 <menu action="FileNewWindowProfiles" />
6 <menuitem action="FileNewTab" />
7 <menu action="FileNewTabProfiles" />
8 <separator />
9 <menuitem action="FileNewProfile" />
10 <menuitem action="FileSaveContents" />
11 <separator />
12 <menuitem action="FileCloseTab" />
13 <menuitem action="FileCloseWindow" />
14 </menu>
15 <menu action="Edit">
16 <menuitem action="EditCopy" />
17 <menuitem action="EditPaste" />
18 <menuitem action="EditPasteURIPaths" />
19 <separator />
20 <menuitem action="EditSelectAll" />
21 <separator />
22 <menuitem action="EditProfiles" />
23 <menuitem action="EditKeybindings" />
24 <menuitem action="EditCurrentProfile" />
25 </menu>
26 <menu action="View">
27 <menuitem action="ViewMenubar" />
28 <menuitem action="ViewFullscreen" />
29 <separator />
30 <menuitem action="ViewZoomIn" />
31 <menuitem action="ViewZoomOut" />
32 <menuitem action="ViewZoom100" />
33 </menu>
34 <menu action="Search">
35 <menuitem action="SearchFind"/>
36 <menuitem action="SearchFindNext"/>
37 <menuitem action="SearchFindPrevious"/>
38 <!--
39 <menuitem action="SearchIncrementalSearch"/>
40 -->
41 <!--
42 <separator/>
43 <menuitem name="SearchClearHighlight" action="SearchClearHighlight"/>
44 -->
45 <!--
46 <separator/>
47 <menuitem name="SearchGoToLineMenu" action="SearchGoToLine"/>
48 -->
49 </menu>
50 <menu action="Terminal">
51 <menu action="TerminalProfiles" />
52 <menuitem action="TerminalSetTitle" />
53 <menu action="TerminalSetEncoding" >
54 <placeholder name="EncodingsPH" />
55 <separator />
56 <menuitem action="TerminalAddEncoding" />
57 </menu>
58 <separator />
59 <menuitem action="TerminalReset" />
60 <menuitem action="TerminalResetClear" />
61 <separator />
62 <placeholder name="TerminalSizeToPH" />
63 </menu>
64 <menu action="Tabs">
65 <menuitem action="TabsNext" />
66 <menuitem action="TabsPrevious" />
67 <separator />
68 <menuitem action="TabsMoveLeft" />
69 <menuitem action="TabsMoveRight" />
70 <separator />
71 <menuitem action="TabsDetach" />
72 <separator />
73 </menu>
74 <menu action="Help">
75 <menuitem action="HelpContents" />
76 <menuitem action="HelpAbout" />
77 </menu>
78 </menubar>
79
80 <popup name="Popup" action="Popup">
81 <menuitem action="PopupSendEmail" />
82 <menuitem action="PopupCopyEmailAddress" />
83 <menuitem action="PopupCall" />
84 <menuitem action="PopupCopyCallAddress" />
85 <menuitem action="PopupOpenLink" />
86 <menuitem action="PopupCopyLinkAddress" />
87 <separator />
88 <menuitem action="PopupNewTerminal" />
89 <menuitem action="PopupNewTab" />
90 <separator />
91 <menuitem action="PopupCloseTab" />
92 <menuitem action="PopupCloseWindow" />
93 <separator />
94 <menuitem action="PopupCopy" />
95 <menuitem action="PopupPaste" />
96 <menuitem action="PopupPasteURIPaths" />
97 <separator />
98 <menu action="PopupTerminalProfiles">
99 <placeholder name="ProfilesPH" />
100 <separator />
101 <menuitem action="EditCurrentProfile" />
102 </menu>
103 <menuitem action="ViewMenubar" />
104 <menuitem action="PopupLeaveFullscreen" />
105 <separator />
106 <menuitem action="PopupInputMethods" />
107 </popup>
108 <popup name="NotebookPopup" action="NotebookPopup">
109 <menuitem action="TabsMoveLeft"/>
110 <menuitem action="TabsMoveRight"/>
111 <separator />
112 <menuitem action="TerminalSetTitle" />
113 <separator />
114 <menuitem action="FileCloseTab"/>
115 </popup>
116</ui>
0117
=== added directory '.pc/01_onlyshowin.patch'
=== added file '.pc/01_onlyshowin.patch/gnome-terminal.desktop.in.in'
--- .pc/01_onlyshowin.patch/gnome-terminal.desktop.in.in 1970-01-01 00:00:00 +0000
+++ .pc/01_onlyshowin.patch/gnome-terminal.desktop.in.in 2011-05-27 08:11:08 +0000
@@ -0,0 +1,14 @@
1[Desktop Entry]
2_Name=Terminal
3_Comment=Use the command line
4TryExec=gnome-terminal
5Exec=gnome-terminal
6Icon=utilities-terminal
7Type=Application
8X-GNOME-DocPath=gnome-terminal/index.html
9X-GNOME-Bugzilla-Bugzilla=GNOME
10X-GNOME-Bugzilla-Product=gnome-terminal
11X-GNOME-Bugzilla-Component=BugBuddyBugs
12X-GNOME-Bugzilla-Version=@VERSION@
13Categories=GNOME;GTK;Utility;TerminalEmulator;
14StartupNotify=true
015
=== added directory '.pc/02_add_transparency_properties.patch'
=== added directory '.pc/02_add_transparency_properties.patch/src'
=== added file '.pc/02_add_transparency_properties.patch/src/gnome-terminal.schemas.in'
--- .pc/02_add_transparency_properties.patch/src/gnome-terminal.schemas.in 1970-01-01 00:00:00 +0000
+++ .pc/02_add_transparency_properties.patch/src/gnome-terminal.schemas.in 2011-05-27 08:11:08 +0000
@@ -0,0 +1,1302 @@
1<gconfschemafile>
2 <schemalist>
3
4
5
6 <!-- Global settings -->
7
8
9
10 <schema>
11 <key>/schemas/apps/gnome-terminal/global/profile_list</key>
12 <applyto>/apps/gnome-terminal/global/profile_list</applyto>
13 <owner>gnome-terminal</owner>
14 <type>list</type>
15 <list_type>string</list_type>
16 <default>[Default]</default>
17 <locale name="C">
18 <short>List of profiles</short>
19 <long>
20 List of profiles known to gnome-terminal. The list contains
21 strings naming subdirectories relative to
22 /apps/gnome-terminal/profiles.
23 </long>
24 </locale>
25 </schema>
26
27 <schema>
28 <key>/schemas/apps/gnome-terminal/global/default_profile</key>
29 <applyto>/apps/gnome-terminal/global/default_profile</applyto>
30 <owner>gnome-terminal</owner>
31 <type>string</type>
32 <default>Default</default>
33 <locale name="C">
34 <short>Profile to use for new terminals</short>
35 <long>
36 Profile to be used when opening a new window or tab.
37 Must be in profile_list.
38 </long>
39 </locale>
40 </schema>
41
42 <schema>
43 <key>/schemas/apps/gnome-terminal/global/use_mnemonics</key>
44 <applyto>/apps/gnome-terminal/global/use_mnemonics</applyto>
45 <owner>gnome-terminal</owner>
46 <type>bool</type>
47 <default>true</default>
48 <locale name="C">
49 <short>Whether the menubar has access keys</short>
50 <long>
51 Whether to have Alt+letter access keys for the menubar.
52 They may interfere with some applications run inside the terminal
53 so it's possible to turn them off.
54 </long>
55 </locale>
56 </schema>
57
58 <schema>
59 <key>/schemas/apps/gnome-terminal/global/use_menu_accelerators</key>
60 <applyto>/apps/gnome-terminal/global/use_menu_accelerators</applyto>
61 <owner>gnome-terminal</owner>
62 <type>bool</type>
63 <default>true</default>
64 <locale name="C">
65 <short>Whether the standard GTK shortcut for menubar access is enabled</short>
66 <long>
67 Normally you can access the menubar with F10. This can also
68 be customized via gtkrc (gtk-menu-bar-accel =
69 "whatever"). This option allows the standard menubar
70 accelerator to be disabled.
71 </long>
72 </locale>
73 </schema>
74
75
76 <schema>
77 <key>/schemas/apps/gnome-terminal/global/active_encodings</key>
78 <applyto>/apps/gnome-terminal/global/active_encodings</applyto>
79 <owner>gnome-terminal</owner>
80 <type>list</type>
81 <list_type>string</list_type>
82 <locale name="C">
83 <default><!-- Translators: Please note that this has to be a list of
84 valid encodings (which are to be taken from the list in src/encoding.c).
85 It has to include UTF-8 and the word 'current', which is not to be
86 translated. This is provided for customization of the default encoding
87 menu; see bug 144810 for an use case. In most cases, this should be
88 left alone. -->[UTF-8,current]</default>
89 <short>List of available encodings</short>
90 <long>
91 A subset of possible encodings are presented in
92 the Encoding submenu. This is a list of encodings
93 to appear there. The special encoding name "current"
94 means to display the encoding of the current locale.
95 </long>
96 </locale>
97 </schema>
98
99 <schema>
100 <key>/schemas/apps/gnome-terminal/global/confirm_window_close</key>
101 <applyto>/apps/gnome-terminal/global/confirm_window_close</applyto>
102 <owner>gnome-terminal</owner>
103 <type>bool</type>
104 <default>true</default>
105 <locale name="C">
106 <short>Whether to ask for confirmation when closing terminal windows</short>
107 <long>
108 Whether to ask for confirmation when closing a terminal window which has
109 more than one open tab.
110 </long>
111 </locale>
112 </schema>
113
114
115
116
117 <!-- Per-profile settings -->
118
119
120
121
122 <schema>
123 <key>/schemas/apps/gnome-terminal/profiles/Default/visible_name</key>
124 <applyto>/apps/gnome-terminal/profiles/Default/visible_name</applyto>
125 <owner>gnome-terminal</owner>
126 <type>string</type>
127 <locale name="C">
128 <default>Default</default>
129 <short>Human-readable name of the profile</short>
130 <long>
131 Human-readable name of the profile.
132 </long>
133 </locale>
134 </schema>
135
136 <schema>
137 <key>/schemas/apps/gnome-terminal/profiles/Default/default_show_menubar</key>
138 <applyto>/apps/gnome-terminal/profiles/Default/default_show_menubar</applyto>
139 <owner>gnome-terminal</owner>
140 <type>bool</type>
141 <default>true</default>
142 <locale name="C">
143 <short>Whether to show menubar in new windows/tabs</short>
144 <long>
145 True if the menubar should be shown in new windows,
146 for windows/tabs with this profile.
147 </long>
148 </locale>
149 </schema>
150
151 <schema>
152 <key>/schemas/apps/gnome-terminal/profiles/Default/foreground_color</key>
153 <applyto>/apps/gnome-terminal/profiles/Default/foreground_color</applyto>
154 <owner>gnome-terminal</owner>
155 <type>string</type>
156 <default>#000000</default>
157 <locale name="C">
158 <short>Default color of text in the terminal</short>
159 <long>
160 Default color of text in the terminal, as a color
161 specification (can be HTML-style hex digits, or
162 a color name such as "red").
163 </long>
164 </locale>
165 </schema>
166
167 <schema>
168 <key>/schemas/apps/gnome-terminal/profiles/Default/background_color</key>
169 <applyto>/apps/gnome-terminal/profiles/Default/background_color</applyto>
170 <owner>gnome-terminal</owner>
171 <type>string</type>
172 <default>#FFFFDD</default>
173 <locale name="C">
174 <short>Default color of terminal background</short>
175 <long>
176 Default color of terminal background, as a color
177 specification (can be HTML-style hex digits, or
178 a color name such as "red").
179 </long>
180 </locale>
181 </schema>
182
183 <schema>
184 <key>/schemas/apps/gnome-terminal/profiles/Default/bold_color</key>
185 <applyto>/apps/gnome-terminal/profiles/Default/bold_color</applyto>
186 <owner>gnome-terminal</owner>
187 <type>string</type>
188 <default>#000000</default>
189 <locale name="C">
190 <short>Default color of bold text in the terminal</short>
191 <long>
192 Default color of bold text in the terminal, as a color
193 specification (can be HTML-style hex digits, or
194 a color name such as "red").
195 This is ignored if bold_color_same_as_fg is true.
196 </long>
197 </locale>
198 </schema>
199
200 <schema>
201 <key>/schemas/apps/gnome-terminal/profiles/Default/bold_color_same_as_fg</key>
202 <applyto>/apps/gnome-terminal/profiles/Default/bold_color_same_as_fg</applyto>
203 <owner>gnome-terminal</owner>
204 <type>bool</type>
205 <default>true</default>
206 <locale name="C">
207 <short>Whether bold text should use the same color as normal text</short>
208 <long>
209 If true, boldface text will be rendered using the same color as
210 normal text.
211 </long>
212 </locale>
213 </schema>
214
215 <schema>
216 <key>/schemas/apps/gnome-terminal/profiles/Default/title_mode</key>
217 <applyto>/apps/gnome-terminal/profiles/Default/title_mode</applyto>
218 <owner>gnome-terminal</owner>
219 <type>string</type>
220 <default>replace</default>
221 <locale name="C">
222 <short>What to do with dynamic title</short>
223 <long>
224 If the application in the terminal sets the title
225 (most typically people have their shell set up to
226 do this), the dynamically-set title can
227 erase the configured title, go before it, go after it,
228 or replace it. The possible values are "replace",
229 "before", "after", and "ignore".
230 </long>
231 </locale>
232 </schema>
233
234 <schema>
235 <key>/schemas/apps/gnome-terminal/profiles/Default/title</key>
236 <applyto>/apps/gnome-terminal/profiles/Default/title</applyto>
237 <owner>gnome-terminal</owner>
238 <type>string</type>
239 <locale name="C">
240 <default>Terminal</default>
241 <short>Title for terminal</short>
242 <long>
243 Title to display for the terminal window or tab.
244 This title may be replaced by or combined with
245 the title set by the application inside the terminal,
246 depending on the title_mode setting.
247 </long>
248 </locale>
249 </schema>
250
251 <schema>
252 <key>/schemas/apps/gnome-terminal/profiles/Default/allow_bold</key>
253 <applyto>/apps/gnome-terminal/profiles/Default/allow_bold</applyto>
254 <owner>gnome-terminal</owner>
255 <type>bool</type>
256 <default>true</default>
257 <locale name="C">
258 <short>Whether to allow bold text</short>
259 <long>
260 If true, allow applications in the terminal to make
261 text boldface.
262 </long>
263 </locale>
264 </schema>
265
266 <schema>
267 <key>/schemas/apps/gnome-terminal/profiles/Default/silent_bell</key>
268 <applyto>/apps/gnome-terminal/profiles/Default/silent_bell</applyto>
269 <owner>gnome-terminal</owner>
270 <type>bool</type>
271 <default>false</default>
272 <locale name="C">
273 <short>Whether to silence terminal bell</short>
274 <long>
275 If true, don't make a noise when applications send the
276 escape sequence for the terminal bell.
277 </long>
278 </locale>
279 </schema>
280
281 <schema>
282 <key>/schemas/apps/gnome-terminal/profiles/Default/word_chars</key>
283 <applyto>/apps/gnome-terminal/profiles/Default/word_chars</applyto>
284 <owner>gnome-terminal</owner>
285 <type>string</type>
286 <default>-A-Za-z0-9,./?%&amp;#:_=+@~</default>
287 <locale name="C">
288 <short>Characters that are considered "part of a word"</short>
289 <long>
290 When selecting text by word, sequences of these characters
291 are considered single words. Ranges can be given as
292 "A-Z". Literal hyphen (not expressing a range) should be
293 the first character given.
294 </long>
295 </locale>
296 </schema>
297
298 <schema>
299 <key>/schemas/apps/gnome-terminal/profiles/Default/use_custom_default_size</key>
300 <applyto>/apps/gnome-terminal/profiles/Default/use_custom_default_size</applyto>
301 <owner>gnome-terminal</owner>
302 <type>bool</type>
303 <default>false</default>
304 <locale name="C">
305 <short>Whether to use custom terminal size for new windows</short>
306 <long>
307 If true, newly created terminal windows will have custom
308 size specified by default_size_columns and default_size_rows.
309 </long>
310 </locale>
311 </schema>
312 <schema>
313 <key>/schemas/apps/gnome-terminal/profiles/Default/default_size_columns</key>
314 <applyto>/apps/gnome-terminal/profiles/Default/default_size_columns</applyto>
315 <owner>gnome-terminal</owner>
316 <type>int</type>
317 <default>80</default>
318 <locale name="C">
319 <short>Default number of columns</short>
320 <long>
321 Number of columns in newly created terminal windows.
322 Has no effect if use_custom_default_size is not enabled.
323 </long>
324 </locale>
325 </schema>
326
327 <schema>
328 <key>/schemas/apps/gnome-terminal/profiles/Default/default_size_rows</key>
329 <applyto>/apps/gnome-terminal/profiles/Default/default_size_rows</applyto>
330 <owner>gnome-terminal</owner>
331 <type>int</type>
332 <default>24</default>
333 <locale name="C">
334 <short>Default number of rows</short>
335 <long>
336 Number of rows in newly created terminal windows.
337 Has no effect if use_custom_default_size is not enabled.
338 </long>
339 </locale>
340 </schema>
341
342 <schema>
343 <key>/schemas/apps/gnome-terminal/profiles/Default/scrollbar_position</key>
344 <applyto>/apps/gnome-terminal/profiles/Default/scrollbar_position</applyto>
345 <owner>gnome-terminal</owner>
346 <type>string</type>
347 <default>right</default>
348 <locale name="C">
349 <short>Position of the scrollbar</short>
350 <long>
351 Where to put the terminal scrollbar. Possibilities are
352 "left", "right", and "hidden".
353 </long>
354 </locale>
355 </schema>
356
357 <schema>
358 <key>/schemas/apps/gnome-terminal/profiles/Default/scrollback_lines</key>
359 <applyto>/apps/gnome-terminal/profiles/Default/scrollback_lines</applyto>
360 <owner>gnome-terminal</owner>
361 <type>int</type>
362 <default>512</default>
363 <locale name="C">
364 <short>Number of lines to keep in scrollback</short>
365 <long>
366 Number of scrollback lines to keep around. You can
367 scroll back in the terminal by this number of lines;
368 lines that don't fit in the scrollback are discarded.
369 If scrollback_unlimited is true, this value is ignored.
370 </long>
371 </locale>
372 </schema>
373
374 <schema>
375 <key>/schemas/apps/gnome-terminal/profiles/Default/scrollback_unlimited</key>
376 <applyto>/apps/gnome-terminal/profiles/Default/scrollback_unlimited</applyto>
377 <owner>gnome-terminal</owner>
378 <type>bool</type>
379 <default>false</default>
380 <locale name="C">
381 <short>Whether an unlimited number of lines should be kept in scrollback</short>
382 <long>
383 If true, scrollback lines will never be discarded. The scrollback
384 history is stored on disk temporarily, so this may cause the system
385 to run out of disk space if there is a lot of output to the
386 terminal.
387 </long>
388 </locale>
389 </schema>
390
391 <schema>
392 <key>/schemas/apps/gnome-terminal/profiles/Default/scroll_on_keystroke</key>
393 <applyto>/apps/gnome-terminal/profiles/Default/scroll_on_keystroke</applyto>
394 <owner>gnome-terminal</owner>
395 <type>bool</type>
396 <default>true</default>
397 <locale name="C">
398 <short>Whether to scroll to the bottom when a key is pressed</short>
399 <long>
400 If true, pressing a key jumps the scrollbar to the bottom.
401 </long>
402 </locale>
403 </schema>
404
405 <schema>
406 <key>/schemas/apps/gnome-terminal/profiles/Default/scroll_on_output</key>
407 <applyto>/apps/gnome-terminal/profiles/Default/scroll_on_output</applyto>
408 <owner>gnome-terminal</owner>
409 <type>bool</type>
410 <default>false</default>
411 <locale name="C">
412 <short>Whether to scroll to the bottom when there's new output</short>
413 <long>
414 If true, whenever there's new output the terminal will scroll
415 to the bottom.
416 </long>
417 </locale>
418 </schema>
419
420 <schema>
421 <key>/schemas/apps/gnome-terminal/profiles/Default/exit_action</key>
422 <applyto>/apps/gnome-terminal/profiles/Default/exit_action</applyto>
423 <owner>gnome-terminal</owner>
424 <type>string</type>
425 <default>close</default>
426 <locale name="C">
427 <short>What to do with the terminal when the child command exits</short>
428 <long>
429 Possible values are "close" to close the terminal, and
430 "restart" to restart the command.
431 </long>
432 </locale>
433 </schema>
434
435 <schema>
436 <key>/schemas/apps/gnome-terminal/profiles/Default/login_shell</key>
437 <applyto>/apps/gnome-terminal/profiles/Default/login_shell</applyto>
438 <owner>gnome-terminal</owner>
439 <type>bool</type>
440 <default>false</default>
441 <locale name="C">
442 <short>Whether to launch the command in the terminal as a login shell</short>
443 <long>
444 If true, the command inside the terminal will be launched as
445 a login shell. (argv[0] will have a hyphen in front of it.)
446 </long>
447 </locale>
448 </schema>
449
450 <schema>
451 <key>/schemas/apps/gnome-terminal/profiles/Default/update_records</key>
452 <applyto>/apps/gnome-terminal/profiles/Default/update_records</applyto>
453 <owner>gnome-terminal</owner>
454 <type>bool</type>
455 <default>true</default>
456 <locale name="C">
457 <short>Whether to update login records when launching terminal command</short>
458 <long>
459 If true, the system login records utmp and wtmp will be updated when the command inside the terminal
460 is launched.
461 </long>
462 </locale>
463 </schema>
464
465 <schema>
466 <key>/schemas/apps/gnome-terminal/profiles/Default/use_custom_command</key>
467 <applyto>/apps/gnome-terminal/profiles/Default/use_custom_command</applyto>
468 <owner>gnome-terminal</owner>
469 <type>bool</type>
470 <default>false</default>
471 <locale name="C">
472 <short>Whether to run a custom command instead of the shell</short>
473 <long>
474 If true, the value of the custom_command setting will
475 be used in place of running a shell.
476 </long>
477 </locale>
478 </schema>
479
480 <schema>
481 <key>/schemas/apps/gnome-terminal/profiles/Default/cursor_blink_mode</key>
482 <applyto>/apps/gnome-terminal/profiles/Default/cursor_blink_mode</applyto>
483 <owner>gnome-terminal</owner>
484 <type>string</type>
485 <default>system</default>
486 <locale name="C">
487 <short>Whether to blink the cursor</short>
488 <long>
489 The possible values are "system" to use the global cursor blinking
490 settings, or "on" or "off" to set the mode explicitly.
491 </long>
492 </locale>
493 </schema>
494
495 <schema>
496 <key>/schemas/apps/gnome-terminal/profiles/Default/cursor_shape</key>
497 <applyto>/apps/gnome-terminal/profiles/Default/cursor_shape</applyto>
498 <owner>gnome-terminal</owner>
499 <type>string</type>
500 <default>block</default>
501 <locale name="C">
502 <short>The cursor appearance</short>
503 <long>
504 The possible values are "block" to use a block cursor, "ibeam" to
505 use a vertical line cursor, or "underline" to use an underline cursor.
506 </long>
507 </locale>
508 </schema>
509
510 <schema>
511 <key>/schemas/apps/gnome-terminal/profiles/Default/custom_command</key>
512 <applyto>/apps/gnome-terminal/profiles/Default/custom_command</applyto>
513 <owner>gnome-terminal</owner>
514 <type>string</type>
515 <default></default>
516 <locale name="C">
517 <short>Custom command to use instead of the shell</short>
518 <long>
519 Run this command in place of the shell, if
520 use_custom_command is true.
521 </long>
522 </locale>
523 </schema>
524
525 <schema>
526 <key>/schemas/apps/gnome-terminal/profiles/Default/icon</key>
527 <applyto>/apps/gnome-terminal/profiles/Default/icon</applyto>
528 <owner>gnome-terminal</owner>
529 <type>string</type>
530 <default></default>
531 <locale name="C">
532 <short>Icon for terminal window</short>
533 <long>
534 Icon to use for tabs/windows containing this profile.
535 </long>
536 </locale>
537 </schema>
538
539 <schema>
540 <key>/schemas/apps/gnome-terminal/profiles/Default/palette</key>
541 <applyto>/apps/gnome-terminal/profiles/Default/palette</applyto>
542 <owner>gnome-terminal</owner>
543 <type>string</type>
544 <default>#2E2E34343636:#CCCC00000000:#4E4E9A9A0606:#C4C4A0A00000:#34346565A4A4:#757550507B7B:#060698209A9A:#D3D3D7D7CFCF:#555557575353:#EFEF29292929:#8A8AE2E23434:#FCFCE9E94F4F:#72729F9FCFCF:#ADAD7F7FA8A8:#3434E2E2E2E2:#EEEEEEEEECEC</default>
545 <locale name="C">
546 <short>Palette for terminal applications</short>
547 <long>
548 Terminals have a 16-color palette that applications inside
549 the terminal can use. This is that palette, in the form
550 of a colon-separated list of color names. Color names
551 should be in hex format e.g. "#FF00FF"
552 </long>
553 </locale>
554 </schema>
555
556 <schema>
557 <key>/schemas/apps/gnome-terminal/profiles/Default/font</key>
558 <applyto>/apps/gnome-terminal/profiles/Default/font</applyto>
559 <owner>gnome-terminal</owner>
560 <type>string</type>
561 <default>Monospace 12</default>
562 <locale name="C">
563 <short>Font</short>
564 <long>
565 An Pango font name. Examples are "Sans 12" or "Monospace Bold 14".
566 </long>
567 </locale>
568 </schema>
569
570 <schema>
571 <key>/schemas/apps/gnome-terminal/profiles/Default/background_type</key>
572 <applyto>/apps/gnome-terminal/profiles/Default/background_type</applyto>
573 <owner>gnome-terminal</owner>
574 <type>string</type>
575 <default>solid</default>
576 <locale name="C">
577 <short>Background type</short>
578 <long>
579 Type of terminal background. May be "solid" for a solid color,
580 "image" for an image, or "transparent" for either real transparency if
581 a compositing window manager is running, or pseudo-transparency
582 otherwise.
583 </long>
584 </locale>
585 </schema>
586
587 <schema>
588 <key>/schemas/apps/gnome-terminal/profiles/Default/background_image</key>
589 <applyto>/apps/gnome-terminal/profiles/Default/background_image</applyto>
590 <owner>gnome-terminal</owner>
591 <type>string</type>
592 <default></default>
593 <locale name="C">
594 <short>Background image</short>
595 <long>
596 Filename of a background image.
597 </long>
598 </locale>
599 </schema>
600
601 <schema>
602 <key>/schemas/apps/gnome-terminal/profiles/Default/scroll_background</key>
603 <applyto>/apps/gnome-terminal/profiles/Default/scroll_background</applyto>
604 <owner>gnome-terminal</owner>
605 <type>bool</type>
606 <default>true</default>
607 <locale name="C">
608 <short>Whether to scroll background image</short>
609 <long>
610 If true, scroll the background image with the foreground
611 text; if false, keep the image in a fixed position and
612 scroll the text above it.
613 </long>
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: