Browse Source

Imported Upstream version 1.8.2

tags/upstream/1.8.2^0
Nicolas Bourdaud 8 years ago
parent
commit
699a0f7d83
100 changed files with 10133 additions and 5265 deletions
  1. +2299
    -146
      cinnamon.pot
  2. +0
    -1773
      config/config.sub
  3. +1
    -1
      configure.ac
  4. +1
    -1
      data/cinnamon.desktop.in.in
  5. +35
    -1
      data/org.cinnamon.gschema.xml.in
  6. +18
    -3
      data/theme/cinnamon.css
  7. +54
    -0
      debian/changelog
  8. +0
    -55
      debian/cinnamon.mk
  9. +1
    -1
      debian/compat
  10. +8
    -10
      debian/control
  11. +0
    -133
      debian/control.in
  12. +41
    -15
      debian/rules
  13. +1
    -0
      debian/source/format
  14. +0
    -2
      debian/watch
  15. +37
    -0
      doc/README.md
  16. +64
    -0
      doc/create-doc.py
  17. +250
    -0
      doc/jstoxml.py
  18. +82
    -0
      doc/style.css
  19. +189
    -0
      doc/xmltohtml.py
  20. +1
    -0
      files/etc/xdg/menus/cinnamon-applications-merged
  21. +3
    -3
      files/etc/xdg/menus/cinnamon-applications.menu
  22. +13
    -8
      files/usr/bin/cinnamon-launcher
  23. +104
    -10
      files/usr/lib/cinnamon-menu-editor/cinnamon-menu-editor.ui
  24. +136
    -34
      files/usr/lib/cinnamon-menu-editor/cme/MainWindow.py
  25. +40
    -18
      files/usr/lib/cinnamon-menu-editor/cme/MenuEditor.py
  26. +3
    -0
      files/usr/lib/cinnamon-menu-editor/cme/util.py
  27. +5
    -1
      files/usr/lib/cinnamon-screensaver-lock-dialog/cinnamon-screensaver-lock-dialog.py
  28. +1223
    -0
      files/usr/lib/cinnamon-settings/bin/ExtensionCore.py
  29. +23
    -8
      files/usr/lib/cinnamon-settings/bin/SettingsWidgets.py
  30. +297
    -141
      files/usr/lib/cinnamon-settings/bin/Spices.py
  31. +4
    -4
      files/usr/lib/cinnamon-settings/bin/XletSettings.py
  32. +101
    -1
      files/usr/lib/cinnamon-settings/bin/XletSettingsWidgets.py
  33. +8
    -0
      files/usr/lib/cinnamon-settings/bin/installSchema.py
  34. +8
    -0
      files/usr/lib/cinnamon-settings/bin/removeSchema.py
  35. +84
    -29
      files/usr/lib/cinnamon-settings/cinnamon-settings.py
  36. +37
    -38
      files/usr/lib/cinnamon-settings/cinnamon-settings.ui
  37. BIN
      files/usr/lib/cinnamon-settings/data/cinnamon.png
  38. +83
    -0
      files/usr/lib/cinnamon-settings/data/icons/default-applications.svg
  39. +439
    -120
      files/usr/lib/cinnamon-settings/data/icons/details.svg
  40. +347
    -0
      files/usr/lib/cinnamon-settings/data/icons/drivers.svg
  41. +177
    -93
      files/usr/lib/cinnamon-settings/data/icons/region.svg
  42. +185
    -0
      files/usr/lib/cinnamon-settings/data/icons/sources.svg
  43. +72
    -0
      files/usr/lib/cinnamon-settings/data/icons/startup-programs.svg
  44. BIN
      files/usr/lib/cinnamon-settings/data/inactive.png
  45. BIN
      files/usr/lib/cinnamon-settings/data/installed.png
  46. BIN
      files/usr/lib/cinnamon-settings/data/running.png
  47. BIN
      files/usr/lib/cinnamon-settings/data/system.png
  48. BIN
      files/usr/lib/cinnamon-settings/data/update.png
  49. BIN
      files/usr/lib/cinnamon-settings/data/user.png
  50. +20
    -853
      files/usr/lib/cinnamon-settings/modules/cs_applets.py
  51. +5
    -4
      files/usr/lib/cinnamon-settings/modules/cs_backgrounds.py
  52. +350
    -0
      files/usr/lib/cinnamon-settings/modules/cs_default.py
  53. +31
    -186
      files/usr/lib/cinnamon-settings/modules/cs_desklets.py
  54. +4
    -1
      files/usr/lib/cinnamon-settings/modules/cs_effects.py
  55. +27
    -95
      files/usr/lib/cinnamon-settings/modules/cs_extensions.py
  56. +0
    -1
      files/usr/lib/cinnamon-settings/modules/cs_general.py
  57. +139
    -0
      files/usr/lib/cinnamon-settings/modules/cs_info.py
  58. +9
    -7
      files/usr/lib/cinnamon-settings/modules/cs_keyboard.py
  59. +187
    -23
      files/usr/lib/cinnamon-settings/modules/cs_mouse.py
  60. +36
    -95
      files/usr/lib/cinnamon-settings/modules/cs_themes.py
  61. +6
    -1
      files/usr/lib/cinnamon-settings/modules/cs_windows.py
  62. +1
    -1
      files/usr/share/applications/cinnamon-settings.desktop
  63. +18
    -10
      files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js
  64. +0
    -1
      files/usr/share/cinnamon/applets/network@cinnamon.org/applet.js
  65. +31
    -12
      files/usr/share/cinnamon/applets/notifications@cinnamon.org/applet.js
  66. +3
    -3
      files/usr/share/cinnamon/applets/power@cinnamon.org/applet.js
  67. +27
    -7
      files/usr/share/cinnamon/applets/settings-example@cinnamon.org/applet.js
  68. +5
    -0
      files/usr/share/cinnamon/applets/settings-example@cinnamon.org/settings-schema.json
  69. +119
    -33
      files/usr/share/cinnamon/applets/sound@cinnamon.org/applet.js
  70. +0
    -1
      files/usr/share/cinnamon/applets/systray@cinnamon.org/applet.js
  71. +13
    -9
      files/usr/share/cinnamon/applets/window-list@cinnamon.org/applet.js
  72. +5
    -1
      files/usr/share/cinnamon/desklets/clock@cinnamon.org/desklet.js
  73. +1
    -1
      files/usr/share/cinnamon/desklets/launcher@cinnamon.org/desklet.js
  74. +125
    -86
      files/usr/share/cinnamon/desklets/photoframe@cinnamon.org/desklet.js
  75. +1
    -1
      files/usr/share/cinnamon/desklets/photoframe@cinnamon.org/metadata.json
  76. +0
    -2
      files/usr/share/gnome-session/sessions/cinnamon.session
  77. +1
    -1
      files/usr/share/gnome-session/sessions/cinnamon2d.session
  78. +1
    -1
      files/usr/share/xsessions/cinnamon2d.desktop
  79. +6
    -2
      js/Makefile.am
  80. +0
    -12
      js/misc/config.js
  81. +1
    -1
      js/misc/windowUtils.js
  82. +438
    -0
      js/ui/appSwitcher/appSwitcher.js
  83. +329
    -0
      js/ui/appSwitcher/appSwitcher3D.js
  84. +277
    -610
      js/ui/appSwitcher/classicSwitcher.js
  85. +214
    -0
      js/ui/appSwitcher/coverflowSwitcher.js
  86. +163
    -0
      js/ui/appSwitcher/timelineSwitcher.js
  87. +226
    -5
      js/ui/applet.js
  88. +2
    -11
      js/ui/appletManager.js
  89. +15
    -0
      js/ui/boxpointer.js
  90. +69
    -47
      js/ui/desklet.js
  91. +169
    -24
      js/ui/deskletManager.js
  92. +112
    -71
      js/ui/dnd.js
  93. +1
    -1
      js/ui/expoThumbnail.js
  94. +21
    -8
      js/ui/extension.js
  95. +43
    -0
      js/ui/keybindings.js
  96. +85
    -81
      js/ui/layout.js
  97. +8
    -1
      js/ui/lookingGlass.js
  98. +283
    -32
      js/ui/main.js
  99. +32
    -52
      js/ui/messageTray.js
  100. +0
    -222
      js/ui/panelMenu.js

+ 2299
- 146
cinnamon.pot
File diff suppressed because it is too large
View File


+ 0
- 1773
config/config.sub
File diff suppressed because it is too large
View File


+ 1
- 1
configure.ac View File

@@ -1,5 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([cinnamon],[1.7.4],[https://bugzilla.gnome.org/enter_bug.cgi?product=cinnamon],[cinnamon])
AC_INIT([cinnamon],[1.8.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=cinnamon],[cinnamon])

AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/cinnamon-global.c])


+ 1
- 1
data/cinnamon.desktop.in.in View File

@@ -2,7 +2,7 @@
Type=Application
_Name=Cinnamon
_Comment=Window management and application launching
Exec=@bindir@/cinnamon
Exec=@bindir@/cinnamon-launcher
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=cinnamon
X-GNOME-Bugzilla-Component=general


+ 35
- 1
data/org.cinnamon.gschema.xml.in View File

@@ -51,6 +51,18 @@
</_description>
</key>

<key name="desklet-snap" type="b">
<default>true</default>
<_summary> Whether desklets "snap" to a grid position</_summary>
<_description> Enabling this allows desklets' position to be snapped into a regular grid</_description>
</key>

<key name="desklet-snap-interval" type="i">
<default>25</default>
<_summary>The interval between each possible grid position when desklets "snap"</_summary>
<_description>If desklet-snap is enabled, the possible positions of desklets will be all integer multiples of the value of "desklet-snap-size"</_description>
</key>

<key name="panel-autohide" type="b">
<default>false</default>
<_summary>Auto-hide panel</_summary>
@@ -124,7 +136,16 @@
Whether the panel icons and text from applets is resized according to the custom panel height
</_description>
</key>

<key name="dnd-drag-threshold" type="i">
<default>8</default>
<range min="1" max="200" />
<_summary>DND drag threshold</_summary>
<_description>
Amount of motion to ignore before registering a drag-and-drop intent on panel objects
</_description>
</key>

<key name="keyboard-applet-use-flags" type="b">
<default>true</default>
<_summary>Use flags to display the keyboard layouts</_summary>
@@ -516,6 +537,11 @@
Controls the style of the ALT-tab window switcher. Can be any combination of "icons", "preview" and "thumbnails", separated by "+".
</_description>
</key>
<key type="b" name="alttab-switcher-enforce-primary-monitor">
<default>false</default>
<_summary>Enforce displaying the alt-tab switcher on the primary monitor instead of the active one</_summary>
</key>

<key name="window-list-applet-scroll" type="b">
<default>false</default>
@@ -569,6 +595,14 @@
<child name="keyboard" schema="org.cinnamon.keyboard"/>
<child name="power" schema="org.cinnamon.power" />
<child name="desklets" schema="org.cinnamon.desklets" />

<key name="enable-vfade" type="b">
<default>false</default>
<_summary>Enable the fade effect in Cinnamon scrollviews</_summary>
<_description>
Whether the vfade effect is enabled or not
</_description>
</key>
</schema>
<schema id="org.cinnamon.theme" path="/org/cinnamon/theme/"


+ 18
- 3
data/theme/cinnamon.css View File

@@ -103,7 +103,6 @@ StScrollBar StButton#vhandle:hover {
color: #ffffff;
font-size: 9.5pt;
min-width: 100px;
background-bumpmap: url("/usr/share/cinnamon/bumpmaps/frost.png");
}
.popup-submenu-menu-item:open {
background-color: #4c4c4c;
@@ -798,7 +797,7 @@ StScrollBar StButton#vhandle:hover {
.switcher-list {
background: rgba(80,80,80,0.8);
border: 2px solid #a5a5a5;
border-radius: 24px;
border-radius: 8px;
padding: 20px;
font-size: 9pt;
color: white;
@@ -1451,7 +1450,7 @@ StScrollBar StButton#vhandle:hover {
.sound-button StIcon {
icon-size: 1.4em;
}
.sound-track-infos {
.sound-track-infos {
padding-left: 5px;
padding-right: 5px;
padding-top: 5px;
@@ -1474,6 +1473,18 @@ StScrollBar StButton#vhandle:hover {
padding-right: 15px;
max-width: 220px;
}
.sound-seek-box {
padding-left: 20px;
}
.sound-seek-box StLabel {
padding-top: 2px;
}
.sound-seek-box StIcon {
icon-size: 1em;
}
.sound-seek-slider {
width: 140px;
}
.sound-volume-menu-item {
padding: .4em 1.75em;
}
@@ -1657,6 +1668,10 @@ StScrollBar StButton#vhandle:hover {
padding: 6px;
}

.desklet-drag-placeholder {
border: 2px solid #6daa00;
background-color: rgba(109,170, 0, 0.3);
}
/* ===================================================================
* Clock Desklet (desklet.js)
* ===================================================================*/


+ 54
- 0
debian/changelog View File

@@ -1,3 +1,57 @@
cinnamon (1.8.2) olivia; urgency=low

* 1.8.2

-- Clement Lefebvre <root@linuxmint.com> Tue, 07 May 2013 14:30:31 +0100

cinnamon (1.8.1) olivia; urgency=low

* 1.8.1

-- Clement Lefebvre <root@linuxmint.com> Tue, 07 May 2013 00:09:09 +0100

cinnamon (1.8.0) olivia; urgency=low

* 1.8.0

-- Clement Lefebvre <root@linuxmint.com> Sun, 05 May 2013 17:40:50 +0100

cinnamon (1.7.10) olivia; urgency=low

* 1.7.10

-- Clement Lefebvre <root@linuxmint.com> Fri, 03 May 2013 21:06:16 +0100

cinnamon (1.7.9) olivia; urgency=low

* 1.7.9

-- Clement Lefebvre <root@linuxmint.com> Fri, 03 May 2013 17:53:50 +0100

cinnamon (1.7.8) olivia; urgency=low

* 1.7.8

-- Clement Lefebvre <root@linuxmint.com> Tue, 30 Apr 2013 17:01:30 +0100

cinnamon (1.7.7) olivia; urgency=low

* 1.7.7

-- Clement Lefebvre <root@linuxmint.com> Sun, 28 Apr 2013 11:40:38 +0100

cinnamon (1.7.6) olivia; urgency=low

* 1.7.6

-- Clement Lefebvre <root@linuxmint.com> Sat, 27 Apr 2013 19:56:06 +0100

cinnamon (1.7.5) olivia; urgency=low

* 1.7.5

-- Clement Lefebvre <root@linuxmint.com> Sat, 27 Apr 2013 19:54:05 +0100

cinnamon (1.7.4) olivia; urgency=low

* 1.7.4


+ 0
- 55
debian/cinnamon.mk View File

@@ -1,55 +0,0 @@
# -*- mode: makefile; coding: utf-8 -*-
# Copyright © 2002 Colin Walters <walters@debian.org>
# Description: A class for GNOME packages; sets up gconf variables, etc
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

# TODO: rewrite to use $(cdbs_make_curbuilddir)

_cdbs_scripts_path ?= /usr/lib/cdbs
_cdbs_rules_path ?= /usr/share/cdbs/1/rules
_cdbs_class_path ?= /usr/share/cdbs/1/class

ifndef _cdbs_class_gnome
_cdbs_class_gnome = 1

include $(_cdbs_class_path)/autotools.mk$(_cdbs_makefile_suffix)

DEB_MAKE_ENVVARS += GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL=1

# for dh_desktop
CDBS_BUILD_DEPENDS_class_gnome ?= debhelper
CDBS_BUILD_DEPENDS += , $(CDBS_BUILD_DEPENDS_class_gnome)

# Most GNOME upstreams don't bother to fix this.
clean::
cd $(DEB_BUILDDIR) && \
rm -f intltool-extract intltool-merge intltool-update po/.intltool-merge-cache; \
if test -d doc; then find doc -name '*.omf.out' -exec rm -f \{\} \; ; fi; \
if test -d help; then find help -name '*.omf.out' -exec rm -f \{\} \; ; fi

# debhelper.mk targets, so silently ignored if debhelper.mk not included
$(patsubst %,binary-install/%,$(DEB_PACKAGES)) :: binary-install/%:
$(if $(wildcard /usr/bin/dh_gconf),dh_gconf -p$(cdbs_curpkg) $(DEB_DH_GCONF_ARGS))
$(if $(wildcard /usr/bin/dh_icons),dh_icons -p$(cdbs_curpkg) $(DEB_DH_ICONS_ARGS))

configure:
./autogen.sh $(DEB_CONFIGURE_EXTRA_FLAGS)
build: configure
dh_auto_build
binary-arch: build

endif

+ 1
- 1
debian/compat View File

@@ -1 +1 @@
7
8

+ 8
- 10
debian/control View File

@@ -1,14 +1,10 @@
# This file is autogenerated. DO NOT EDIT!
#
# Modifications should be made to debian/control.in instead.
# This file is regenerated automatically in the clean target.
Source: cinnamon
Section: gnome
Priority: optional
Maintainer: Linux Mint <root@linuxmint.com>
Build-Depends: cdbs,
debhelper (>= 7),
autotools-dev,
Build-Depends: debhelper (>= 8),
dh-autoreconf,
python-dev,
gnome-pkg-tools (>= 0.11),
intltool,
libgjs-dev (>= 1.29.18),
@@ -55,7 +51,7 @@ Depends: ${gir:Depends},
${shlibs:Depends},
${misc:Depends},
cinnamon-common (= ${source:Version}),
cinnamon-control-center | gnome-control-center,
cinnamon-control-center | gnome-control-center,
caribou,
cups-pk-helper,
gnome-settings-daemon (>= 2.91.5.1),
@@ -82,8 +78,10 @@ Depends: ${gir:Depends},
mesa-utils,
python-lxml,
gkbd-capplet,
python-pyinotify
Recommends: gnome-themes-standard, gnome-terminal, nemo, cinnamon-screensaver
python-pyinotify,
metacity,
gnome-panel | tint2
Recommends: gnome-themes-standard, gnome-terminal, nemo, cinnamon-screensaver, gnome-session-bin, gir1.2-gjsdbus-1.0
Conflicts: cinnamon-session, cinnamon-settings
Provides: cinnamon-session, cinnamon-settings, notification-daemon, x-window-manager
Replaces: cinnamon-session, cinnamon-settings


+ 0
- 133
debian/control.in View File

@@ -1,133 +0,0 @@
Source: cinnamon
Section: gnome
Priority: optional
Maintainer: Linux Mint <root@linuxmint.com>
Build-Depends: cdbs,
debhelper (>= 7),
autotools-dev,
gnome-pkg-tools (>= 0.11),
intltool,
libgjs-dev (>= 1.29.18),
gvfs-backends,
gobject-introspection (>= 1.29.15),
gir1.2-json-1.0,
gnome-bluetooth (>= 3.1.0),
gnome-common,
gsettings-desktop-schemas-dev (>= 0.1.7),
libcaribou-dev,
libcroco3-dev (>= 0.6.2),
libdbus-glib-1-dev,
libgconf2-dev,
libgirepository1.0-dev (>= 1.29.15),
libglib2.0-dev (>= 2.25.9),
libglib2.0-bin (>= 2.25.11),
libgnome-bluetooth-dev (>= 3.1.0),
libgnome-desktop-3-dev (>= 2.90.0),
libgnome-keyring-dev,
libgnome-menu-3-dev,
libgstreamer0.10-dev (>= 0.10.16),
libgtk-3-dev (>= 3.0.0),
libgudev-1.0-dev,
libnm-glib-dev (>= 0.8.999),
libstartup-notification0-dev (>= 0.11),
libmuffin-dev (>= 1.0.5),
librsvg2-dev,
libsoup2.4-dev,
libwnck-dev,
libclutter-1.0-dev (>= 1.7.5),
libxfixes-dev (>= 1:5.0),
libxss-dev,
libpulse-dev,
libcanberra-dev,
libpolkit-agent-1-dev (>= 0.100),
libjson-glib-dev (>= 0.13.2)
Standards-Version: 3.9.1
Homepage: http://cinnamon.linuxmint.com

Package: cinnamon
Architecture: any
Depends: ${gir:Depends},
gjs (>= 1.29.18),
${shlibs:Depends},
${misc:Depends},
cinnamon-common (= ${source:Version}),
cinnamon-control-center | gnome-control-center,
caribou,
cups-pk-helper,
gnome-settings-daemon (>= 2.91.5.1),
gsettings-desktop-schemas (>= 0.1.7),
gnome-icon-theme-symbolic (>= 2.91),
${icon-theme:Depends},
gir1.2-accountsservice-1.0,
gir1.2-gconf-2.0,
gir1.2-gkbd-3.0,
gir1.2-gnomebluetooth-1.0,
gir1.2-gstreamer-0.10,
gir1.2-networkmanager-1.0,
gir1.2-polkit-1.0,
gir1.2-soup-2.4,
gir1.2-upowerglib-1.0,
gir1.2-gtkclutter-1.0,
gir1.2-javascriptcoregtk-3.0,
gir1.2-webkit-3.0,
python,
python-dbus,
python-gconf,
python-imaging,
python-gtk2,
pkg-config,
mesa-utils,
python-lxml,
gkbd-capplet,
python-pyinotify
Recommends: gnome-themes-standard, gnome-terminal, nemo, cinnamon-screensaver
Conflicts: cinnamon-session, cinnamon-settings
Provides: cinnamon-session, cinnamon-settings, notification-daemon, x-window-manager
Replaces: cinnamon-session, cinnamon-settings
Description: Cinnamon desktop
Cinnamon redefines user interactions with the GNOME desktop.
In particular, it offers new paradigms for launching applications,
accessing documents, and organizing open windows in GNOME. Later, it
will introduce a new applets eco-system and offer new solutions for
other desktop features, such as notifications and contacts
management. Cinnamon is intended to replace functions handled
by the GNOME Panel and by the window manager in previous versions of
GNOME. Cinnamon has rich visual effects enabled by new
graphical technologies.

Package: cinnamon-dbg
Section: debug
Priority: extra
Architecture: any
Depends: cinnamon (= ${binary:Version}),
${misc:Depends}
Description: Debugging symbols for the Cinnamon desktop
Cinnamon redefines user interactions with the GNOME desktop.
In particular, it offers new paradigms for launching applications,
accessing documents, and organizing open windows in GNOME. Later, it
will introduce a new applets eco-system and offer new solutions for
other desktop features, such as notifications and contacts
management. Cinnamon is intended to replace functions handled
by the GNOME Panel and by the window manager in previous versions of
GNOME. Cinnamon has rich visual effects enabled by new
graphical technologies.
.
This package contains the debugging symbols.

Package: cinnamon-common
Replaces: cinnamon (<< 1.7.1)
Breaks: cinnamon (<< 1.7.1)
Architecture: all
Depends: ${misc:Depends}, python
Description: Cinnamon desktop (Common data files)
Cinnamon redefines user interactions with the GNOME desktop.
In particular, it offers new paradigms for launching applications,
accessing documents, and organizing open windows in GNOME. Later, it
will introduce a new applets eco-system and offer new solutions for
other desktop features, such as notifications and contacts
management. Cinnamon is intended to replace functions handled
by the GNOME Panel and by the window manager in previous versions of
GNOME. Cinnamon has rich visual effects enabled by new
graphical technologies.
.
This package contains the architecture independent files needed by Cinnamon

+ 41
- 15
debian/rules View File

@@ -1,23 +1,49 @@
#!/usr/bin/make -f
# -*- makefile -*-

include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/autotools.mk
include /usr/share/cdbs/1/rules/utils.mk
include debian/cinnamon.mk
include /usr/share/gnome-pkg-tools/1/rules/uploaders.mk
-include /usr/share/gnome-pkg-tools/1/rules/gnome-get-source.mk
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1

export LDFLAGS+=-Wl,--as-needed

# To avoid running configure twice (because gnome-autogen.sh)
export NOCONFIGURE=yes

ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
DH_PARALLEL_OPTION=--parallel
endif

ifeq ($(cinnamon dpkg-vendor --query vendor),Ubuntu)
DEB_DH_GENCONTROL_ARGS += -- -Vicon-theme:Depends=gnome-icon-theme-full
DH_GENCONTROL_ARGS = -Vicon-theme:Depends=gnome-icon-theme-full
endif

$(patsubst %,binary-predeb/%,$(DEB_ALL_PACKAGES)) ::
dh_girepository -p$(cdbs_curpkg) -l src -p /usr/lib/muffin \
/usr/lib/cinnamon
find debian/$(cdbs_curpkg) -name '*.la' -exec rm -f '{}' ';'
%:
dh $@ --with autoreconf,python2 $(DH_PARALLEL_OPTION)


override_dh_autoreconf:
dh_autoreconf --as-needed ./autogen.sh

override_dh_auto_configure:
dh_auto_configure -- --enable-compile-warnings=yes \
--disable-schemas-install \
BROWSER_PLUGIN_DIR=/usr/lib/mozilla/plugins

# Disable checks since they are not functional for the moment
override_dh_auto_test:

override_dh_install:
dh_install -X.la

override_dh_strip:
dh_strip --dbg-package=cinnamon-dbg

override_dh_makeshlibs:
dh_makeshlibs -Xplugin

DEB_CONFIGURE_EXTRA_FLAGS += --enable-compile-warnings=yes
override_dh_shlibdeps:
dh_shlibdeps
dh_girepository -l src -p/usr/lib/muffin /usr/lib/cinnamon

DEB_DBG_PACKAGES = cinnamon-dbg
DEB_DH_MAKESHLIBS_ARGS_cinnamon = -Xlibcinnamon
DEB_SHLIBDEPS_INCLUDE = /usr/lib/gnome-bluetooth
override_dh_gencontrol:
dh_gencontrol -- $(DH_GENCONTROL_ARGS)

+ 1
- 0
debian/source/format View File

@@ -0,0 +1 @@
3.0 (native)

+ 0
- 2
debian/watch View File

@@ -1,2 +0,0 @@
version=3
http://download.gnome.org/sources/cinnamon/([\d\.]+)/cinnamon-(.*)\.tar\.bz2

+ 37
- 0
doc/README.md View File

@@ -0,0 +1,37 @@
Running ./create-do.py will parse JS code in js/ui/ into html documentation.

The html files will be created in Cinnamon/doc/output-html/

Format of Documentation
=======================
Functions
---------
/**
* function_name:
* @agrument_one (ArgumentType): argument description
* @agrument_two (ArgumentType): argument description
*
* How the function works. Long description (capitalize first letter)
*
* Returns (ReturnType): what the function returns
*/

Objects
-------
/**
* #ObjectName:
* @variable1_of_object (VarType): variable description
* @variable2_of_object (VarType): variable description
*
* Description of object
*/

File
----
/**
* FILE:filename.js
*
* Description of file
*/


+ 64
- 0
doc/create-doc.py View File

@@ -0,0 +1,64 @@
#!/usr/bin/env python
#-*- indent-tabs-mode: nil-*-

import sys
import os
import shutil
import jstoxml
import xmltohtml

CURRDIR = os.path.abspath(os.path.dirname(sys.argv[0])) + "/"
JS_DIR = CURRDIR + "../js/ui/"
XML_DIR = CURRDIR + "output-xml/"
HTML_DIR = CURRDIR + "output-html/"

if __name__ == "__main__":
files = os.listdir(JS_DIR)
files.sort()
try:
os.mkdir(XML_DIR)
except Exception:
pass

try:
os.mkdir(HTML_DIR)
except Exception:
pass

errors = [] # Store the files that failed to parse
# Removing them in loop will break the loop
for _file in files:
print "Parsing " + _file
__file = _file[:-3]

try:
xml = jstoxml.convertJStoXML(JS_DIR + __file + ".js")
xml.write(XML_DIR + __file + ".xml")

html = xmltohtml.convertXMLtoHTML(XML_DIR + __file + ".xml")
open(HTML_DIR + __file + ".html", "w").write(html)
except:
print "Error parsing " + _file + ". Skipping"
errors.append(_file)

shutil.copy2('style.css', HTML_DIR)

html = []
html.extend(["<!DOCTYPE html>",
"<html>",
"<head>",
"<title>Cinnamon Documentation Index</title>",
"<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />\n</head>",
"<body>",
"<p class=\"page-header\">Cinnamon JS Documentation</p>",
"<ul class=\"index-page-list\">"])

for _file in files:
if _file not in errors:
html.extend(["<li><a href=\"%s.html\">%s</a></li>" % (_file[:-3], _file)])

html.extend(["</ul>",
"</body>",
"</html>"])
open(HTML_DIR + "index.html", "w").write("\n".join(html))


+ 250
- 0
doc/jstoxml.py View File

@@ -0,0 +1,250 @@
#!/usr/bin/env python
#-*- indent-tabs-mode: nil-*-


import sys
import io
import os
import xml.etree.ElementTree as ET

# Constant objects
ITEM_TYPE_OBJECT = 0
ITEM_TYPE_FUNCTION = 1
ITEM_TYPE_FILE = 2

# Reads a file and return the lines (as an array)
def readFile(filename):
_file = open(filename, "r")
content = _file.readlines()
_file.close()
return content

# Gets a "function block", i.e. those starting and ending with "{" and "}",
# e.g. a function/prototype declaration
#
# Returns [start, end], where "start" and "end" are the line numbers of the start and end of the block
def getFunctionBlock(lines, init_line = 0):
brackets = 0 # Number of "{" - Number of "}"
start = 0 # Starting line number of the block
end = 0 # Ending line number of the block

i = init_line
try:
while "{" not in lines[i]:
i = i + 1
# Now we are at the first line of the block
start = i
brackets = brackets + lines[i].count("{") - lines[i].count("}")
except:
start = i-1

try:
while brackets > 0:
i = i + 1
brackets = brackets + lines[i].count("{") - lines[i].count("}")
end = i
except:
end = i - 1

return [start,end]

def getCommentBlock(lines, init_line = 0):
i = init_line
try:
while "/**" not in lines[i]:
i = i + 1
except:
i = i - 1
start = i
try:
while "*/" not in lines[i]:
i = i + 1
except:
i = i - 1

end = i
return [start,end]

def parseCommentBlock(lines):
try:
del lines[0], lines[-1] # Strip first and last line

itemType = None
itemName = ""
itemProps = []
itemDescription = ""

# Parse the file
# Strip the " * " part
for i in range(len(lines)):
lines[i] = lines[i].lstrip()
lines[i] = lines[i][1:]
lines[i] = lines[i].lstrip()
lines[i] = lines[i].replace("\n", "")

nameLine = lines[0].strip()
if nameLine.find("#") == 0:
itemType = ITEM_TYPE_OBJECT
itemName = nameLine[1:]
elif nameLine.find("FILE:") == 0:
itemType = ITEM_TYPE_FILE
itemName = nameLine[5:].lstrip()
else:
itemType = ITEM_TYPE_FUNCTION
itemName = nameLine

itemName = itemName.replace(":","") # Remove the : at the end of definition

del lines[0]

# Item properties
propName = ""
i = 0
while len(lines) > 0 and len(lines[0].strip()) != 0:
line = lines[0]
if ("@" in line):
line = line[1:] # Strip "@" sign
propName = line[:line.find(":")].encode()
line = line[line.find(":")+1:]
itemProps.append([propName, ""])
itemProps[-1][1] = itemProps[-1][1] + line + " "
del lines[0]

# Item description
if len(lines) > 0:
del lines[0] # Remove separating linebreak

while len(lines) > 0 and lines[0].find("Returns") == -1:
itemDescription = itemDescription + " " + lines[0].strip()
del lines[0]

itemDescription = itemDescription.replace(" ", "\n\n")

# Return data
returnData = " ".join(lines)
if len(returnData.strip()) > 0:
returnData = returnData.strip()[7:] # Strip "Returns"
returnData = returnData.split(":") # Split into return type and
returnData[0] = returnData[0].strip() # Strip whitespaces again
returnData[0] = returnData[0][1:-1] # Remove brackets
returnData[1] = returnData[1].strip() # Strip whitespaces
else:
returnData = ["void", None]


return [itemType, itemName, itemProps, itemDescription, returnData]
except Exception:
return [None, None, None, None, None]

def addVariables(element, variables):
for i in variables:
_name = i[0]
_desc = i[1]
hasType = "(" in _name
if hasType:
propName = _name[:_name.find("(")].strip()
propType = _name[_name.find("(") + 1: _name.rfind(")")]
else:
propName = _name
propType = ""
prop = ET.SubElement(element, 'prop', {'name': propName, 'type': propType})
prop.text = _desc

def createFunctionElement(element, itemName, itemProps, itemDescription, itemReturn):
name = ET.SubElement(element, 'name')
name.text = itemName

desc = ET.SubElement(element, 'description')
desc.text = itemDescription

addVariables(element, itemProps)

# Set the return
ret = ET.SubElement(element, 'return', {'type': itemReturn[0]})
if itemReturn[1]:
ret.text = itemReturn[1]

return element

def convertJStoXML(filename):
lines = readFile(filename)
shortFileName = filename[filename.rfind("/")+1:]
root = ET.Element('file')
name = ET.SubElement(root, 'name')
name.text = shortFileName

xmlTree = ET.ElementTree(root)
while (len(lines)> 0):
[start, end] = getCommentBlock(lines)
if start == end:
break
newlines = lines[start:end+1]

[itemType, itemName, itemProps, itemDescription, itemReturn] = parseCommentBlock(newlines)
if itemType == ITEM_TYPE_FILE:
# Check that this refers to the current file
if itemName != shortFileName:
del lines[:end]
continue;

desc = ET.SubElement(root, 'description')
desc.text = itemDescription

addVariables(root, itemProps)
if itemType == ITEM_TYPE_FUNCTION:
# Check that this refers to the correct function
_start = end
[_start, _end] = getFunctionBlock(lines, _start)
if "function" + itemName + "(" not in lines[_start].replace(" ",""):
del lines[:_end]
continue

element = ET.SubElement(root, 'function')
createFunctionElement(element, itemName, itemProps, itemDescription, itemReturn)

if itemType == ITEM_TYPE_OBJECT:
element = ET.SubElement(root, 'object')

name = ET.SubElement(element, 'name')
name.text = itemName

desc = ET.SubElement(element, 'description')
desc.text = itemDescription

addVariables(element, itemProps)

# Find range of object declaration
_start = end
[_start, _end] = getFunctionBlock(lines, _start)

while lines[_start].strip().find(itemName + ".prototype") != 0:
_start = _end
[_start, _end] = getFunctionBlock(lines, _start)

inlines = lines[_start:_end+1]
end = _end

# Parse the functions inside
while len(inlines) > 0:
[inStart, inEnd] = getCommentBlock(inlines)
if inStart == inEnd:
break
newLines = inlines[inStart:inEnd+1]
[itemType, itemName, itemProps, itemDescription, itemReturn] = parseCommentBlock(newLines)
if itemType == ITEM_TYPE_FUNCTION:
__start = inStart
[__start, __end] = getFunctionBlock(inlines, __start)
if itemName + ":function(" not in inlines[__start].replace(" ", ""):
del inlines[:__end]
continue
subelement = ET.SubElement(element, 'function')
createFunctionElement(subelement, itemName, itemProps, itemDescription, itemReturn)

del inlines[:inEnd]
del lines[:end]

return xmlTree

+ 82
- 0
doc/style.css View File

@@ -0,0 +1,82 @@
body {
}
.page-header {
font-size: 180%;
font-weight: bold;
}

h2 {
font-family: Cantarell, 'Droid Sans', Ubuntu, 'DejaVu Sans', Arial, sans-serif;
color: #0489b7;
}
.index-page-list {
}

.description{
}

.prop-prop-separator {
color: #babdb6;
background: #babdb6;
border: none 0px;
height: 1px;
clear: both;
}

.obj-obj-separator {
}

.prop-table{
background: #eeeeee;
border: solid 1px #babdb6;
padding: 0.5em;
}

.prop-table-return {
}

.prop-table-name {
padding-left: 50px;
}

.prop-table-arg {
padding-left: 50px;
}

.prop-table-arg-type {
color: #666;
}

.prop-table-arg-name {
}

.prop-table-line-break {
height: 5px;
}

.prop-arg-table {
padding-left: 50px;
}

.prop-arg-name {
background-color: #e5e5e5;
padding: 2px 5px;
}

.prop-arg-description {
padding-left: 5px;
}
n
.prop-return-name {
background-color: #ccc;
padding: 2px 5px;
}

.prop-return-description {
padding-left: 5px;
}

.individual-prop-header {
font-size: 110%;
font-weight: bold;
}

+ 189
- 0
doc/xmltohtml.py View File

@@ -0,0 +1,189 @@
#!/usr/bin/env python
#-*- indent-tabs-mode: nil-*-

import sys
import io
import os
import xml.etree.ElementTree as ET

def loadVarRow(item, elementName, link):
html = []
html.extend(["<tr>",
"<td><code class=\"prop-table-type\">%s</code></td>" % item[1],
"<td>"])
if link:
html.extend(["<a href=\"#%s.%s\">" % (elementName, item[0])])
html.extend(["<code class=\"prop-table-name\">%s</code>" % item[0]])

if link:
html.extend(["</a>"])
html.extend(["</td>",
"</tr>"])
return html

def loadFunctionRow(item, elementName, link):
html = []
html.extend(["<tr>",
"<td><code class=\"prop-table-return\">%s</code></td>" % item[3].get("type"),
"<td>"])
if link:
html.extend(["<a href=\"#%s.%s\">" % (elementName, item[0])])

html.extend(["<code class=\"prop-table-name\">%s</code>" % item[0]])

if link:
html.extend(["</a>"])

html.extend(["</td>",
"<td class=\"prop-table-arg\">("])

for prop in item[2]:
html.extend(["<code class=\"prop-table-arg-type\">%s</code>" % prop.get("type"),
"<code class=\"prop-table-arg-name\">%s,</code>"% prop.get("name"),
"</td></tr><tr><td /><td /><td class=\"prop-table-arg\">&nbsp"])
if len(item[2]) > 0:
del html[-1] # Delete the previous end line
html[-1] = html[-1].replace(",", "") # Delete the comma
html.extend([")</td>",
"</tr>"])

return html

def loadElement(element, elementName):
html = []

# Load short description
for child in element:
if child.tag == "short-description":
if child.text:
html.extend(["<p class=\"short-description\">",
child.text.replace("\n", "<br />"),
"</p>"])

# Load function and variable lists
var_list = []
for child in element:
if child.tag == "prop":
var_list.append([child.get("name"), child.get("type"), child.text])

functions_list = []
for child in element:
if child.tag == "function":
functions_list.append([child.findtext("name"), child.findtext("description").replace("\n", "<br />"), child.findall("prop"), child.find("return")])


# Load synopsis
if len(functions_list) > 0 or len(var_list) > 0:
html.extend(["<h2>Synopsis</h2>"]);
html.extend(["<table class=\"prop-table\">"])
for item in functions_list:
html.extend(loadFunctionRow(item, elementName, True))
html.extend(["<tr class=\"prop-table-line-break\" />"])
for item in var_list:
html.extend(loadVarRow(item, elementName, True))
html.extend(["<tr class=\"prop-table-line-break\" />"])
html.extend(["</table>"])

# Load long description
for child in element:
if child.tag == "description":
if child.text:
html.extend(["<h2>Description</h2>"]);
html.extend(["<p class=\"description\">",
child.text.replace("\n", "<br />"),
"</p>"])
break

# Load individual functions
if len(functions_list) > 0:
html.extend(["<h2>Details</h2>"])
for item in functions_list:
# Header
html.extend(["<br /><a id=\"%s.%s\" class=\"individual-prop-header\">%s ()</a>" % (elementName, item[0], item[0])])

# Table showing format of function (similar to that in function list)
html.extend(["<table class=\"prop-table\">"])
html.extend(loadFunctionRow(item, elementName, False))
html.extend(["</table>"])

# Description of the function
html.extend(["<p class=\"prop-description\">%s</p>" % item[1]])

# List arguments and relevant descriptions
html.extend(["<table class=\"prop-arg-table\">"])
if len(item[2]) > 0:
for prop in item[2]:
html.extend(["<tr>",
"<td class=\"prop-arg-name\">",
prop.get("name"),
"</td><td class=\"prop-arg-description\">",
prop.text,
"</td></tr>"])
if item[3].text:
html.extend(["<tr>",
"<td class=\"prop-return-name\">",
"Return",
"</td><td class=\"prop-return-description\">",
item[3].text,
"</td></tr>"])
html.extend(["</table>"])

# Add separator
html.extend(["<hr class=\"prop-prop-separator\" />"])

for item in var_list:
html.extend(["<br /><a id=\"%s.%s\" class=\"individual-prop-header\">%s</a>" % (elementName, item[0], item[0])])

# Table showing the variable (similar to that in function list)
html.extend(["<table class=\"prop-table\">"])
html.extend(loadVarRow(item, elementName, False))
html.extend(["</table>"])

# Description of the variable
html.extend(["<p class=\"prop-description\">%s</p>" % item[2]])

# Add separator
html.extend(["<hr class=\"prop-prop-separator\" />"])

# Remove last separator
del html[-1]

return html

def convertXMLtoHTML(xml):
tree = ET.parse(xml)
root = tree.getroot()

html = []
_name = root.find("name").text
name = _name[0].upper() + _name[1:-3]

# Standard HTML heading
html.extend(["<!DOCTYPE html>",
"<html>",
"<head>",
"<title>%s</title>" % name,
"<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />\n</head>",
"<body>",
"<p class=\"page-header\">%s</p>" % name])

html.extend(loadElement(root, name))

objects_list = []
for child in root:
if child.tag == "object":
objects_list.append(child)

for item in objects_list:
# Add separator
html.extend(["<hr class=\"obj-obj-separator\" />"])
# Show header
html.extend(["<h2>%s.%s</h2>" % (name, item.findtext("name"))])
html.extend(loadElement(item, name + "." + item.findtext("name")))

# Standard HTML ending
html.extend(["</body>",
"</html>"])

return "\n".join(html)

+ 1
- 0
files/etc/xdg/menus/cinnamon-applications-merged View File

@@ -0,0 +1 @@
applications-merged

+ 3
- 3
files/etc/xdg/menus/cinnamon-applications.menu View File

@@ -150,10 +150,10 @@
</And>
</Include>
</Menu> <!-- End Other -->
<!-- Wine -->
<!-- Wine -->
<Menu>
<Name>Wine</Name>
<Name>wine-wine</Name>
<Directory>wine-wine.directory</Directory>
<Include>
<And>


+ 13
- 8
files/usr/bin/cinnamon-launcher View File

@@ -7,12 +7,12 @@ FALLBACK_ARGS = ("--replace",)
import os, sys, gettext
from gi.repository import Gtk

gettext.install("cinnamon", "/usr/share/linuxmint/locale")
gettext.install("cinnamon", "/usr/share/cinnamon/locale")

def confirm(message):
d = Gtk.MessageDialog(None, 0, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO)
def confirm_restart():
d = Gtk.MessageDialog(None, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO)
d.set_keep_above(True)
d.set_markup("<span size='large'><b>%s</b></span>" % message)
d.set_markup("<span size='large'><b>%s</b></span>\n\n%s" % (_("Do you want to restart Cinnamon?"), _("Cinnamon just crashed. You are currently running in Fallback Mode.")))
d.show_all()
resp = d.run()
d.destroy()
@@ -21,12 +21,17 @@ def confirm(message):
if __name__ == "__main__":
cinnamon_pid = os.fork()
if cinnamon_pid == 0:
os.execvp("cinnamon", ("",) + tuple(sys.argv[1:]))
os.execvp("cinnamon", ("cinnamon", "--replace", ) + tuple(sys.argv[1:]))
else:
exit_status = os.waitpid(cinnamon_pid, 0)[1]
if exit_status != 0:
if os.fork() == 0:
os.execvp(FALLBACK_COMMAND, ("",) + FALLBACK_ARGS)
if os.path.exists("/usr/bin/gnome-panel"):
os.system("gnome-panel --replace &")
elif os.path.exists("/usr/bin/tint2"):
os.system("killall tint2")
os.system("tint2 &")
os.execvp(FALLBACK_COMMAND, (FALLBACK_COMMAND,) + FALLBACK_ARGS)
else:
if confirm(_("Cinnamon crashed.\nDo you want to restart it ?")):
os.execvp(sys.argv[0], ("", "--replace"))
if confirm_restart():
os.execvp(sys.argv[0], (sys.argv[0], "--replace"))

+ 104
- 10
files/usr/lib/cinnamon-menu-editor/cinnamon-menu-editor.ui View File

@@ -4,6 +4,28 @@
<object class="GtkUIManager" id="uimanager1">
<child>
<object class="GtkActionGroup" id="actiongroup1">

<child>
<object class="GtkAction" id="edit_cut">
<property name="stock_id">gtk-cut</property>
<property name="name">edit_cut</property>
<signal handler="on_edit_cut_activate" name="activate"/>
</object>
</child>
<child>
<object class="GtkAction" id="edit_copy">
<property name="stock_id">gtk-copy</property>
<property name="name">edit_copy</property>
<signal handler="on_edit_copy_activate" name="activate"/>
</object>
</child>
<child>
<object class="GtkAction" id="edit_paste">
<property name="stock_id">gtk-paste</property>
<property name="name">edit_paste</property>
<signal handler="on_edit_paste_activate" name="activate"/>
</object>
</child>
<child>
<object class="GtkAction" id="edit_properties">
<property name="stock_id">gtk-properties</property>
@@ -22,20 +44,19 @@
</child>
<ui>
<popup name="edit_menu">
<menuitem action="edit_properties"/>
<menuitem action="edit_cut"/>
<menuitem action="edit_copy"/>
<menuitem action="edit_paste"/>
<separator/>
<menuitem action="edit_delete"/>
<separator/>
<menuitem action="edit_properties"/>
</popup>
</ui>
</object>
<object class="GtkMenu" constructor="uimanager1" id="edit_menu">




</object>
<object class="GtkDialog" id="mainwindow">
<property name="border_width">5</property>
@@ -147,7 +168,10 @@
<property name="fixed_height_mode">False</property>
<property name="hover_selection">False</property>
<property name="hover_expand">False</property>
<signal handler="on_item_tree_row_activated" name="row-activated"/>
<signal handler="on_menu_tree_cursor_changed" name="cursor-changed"/>
<signal handler="on_menu_tree_popup_menu" name="popup-menu"/>
<signal handler="on_menu_tree_popup_menu" name="button_press_event"/>
</object>
</child>
</object>
@@ -290,6 +314,76 @@
<signal handler="on_move_down_button_clicked" name="clicked"/>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment20">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">1</property>
<property name="yscale">1</property>
<property name="top_padding">12</property>
<property name="bottom_padding">0</property>
<property name="left_padding">0</property>
<property name="right_padding">0</property>
<child>
<object class="GtkVButtonBox" id="vbuttonbox5">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_START</property>
<property name="spacing">6</property>
<child>
<object class="GtkButton" id="cut_button">
<property name="label" translatable="no">gtk-cut</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal handler="on_cut_button_clicked" name="clicked"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="copy_button">
<property name="label" translatable="no">gtk-copy</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal handler="on_copy_button_clicked" name="clicked"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="paste_button">
<property name="label" translatable="no">gtk-paste</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal handler="on_paste_button_clicked" name="clicked"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="delete_button">
<property name="label" translatable="no">gtk-delete</property>
@@ -302,7 +396,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
<property name="position">3</property>
</packing>
</child>
<child>
@@ -312,12 +406,12 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal handler="on_properties_button_clicked" name="clicked"/>
<signal handler="on_properties_button_clicked" name="clicked"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
<property name="position">4</property>
</packing>
</child>
</object>


+ 136
- 34
files/usr/lib/cinnamon-menu-editor/cme/MainWindow.py View File

@@ -50,8 +50,14 @@ class MainWindow(object):
self.setupItemTree()
self.tree.get_object('edit_delete').set_sensitive(False)
self.tree.get_object('edit_properties').set_sensitive(False)
self.tree.get_object('edit_cut').set_sensitive(False)
self.tree.get_object('edit_copy').set_sensitive(False)
self.tree.get_object('edit_paste').set_sensitive(False)
self.tree.get_object('move_up_button').set_sensitive(False)
self.tree.get_object('move_down_button').set_sensitive(False)
self.cut_copy_buffer = None
self.file_id = None
self.last_tree = None

def run(self):
self.loadMenus()
@@ -83,10 +89,10 @@ class MainWindow(object):
update_menus = False
menu_id = None
if iter:
if menus[iter][2].get_desktop_file_path():
menu_id = os.path.split(menus[iter][2].get_desktop_file_path())[1]
if menus[iter][3].get_desktop_file_path():
menu_id = os.path.split(menus[iter][3].get_desktop_file_path())[1]
else:
menu_id = menus[iter][2].get_menu_id()
menu_id = menus[iter][3].get_menu_id()
update_menus = True
self.loadMenus()
#find current menu in new tree
@@ -127,23 +133,23 @@ class MainWindow(object):
return False

def findMenu(self, menus, path, iter, menu_id):
if not menus[path][2].get_desktop_file_path():
if menu_id == menus[path][2].get_menu_id():
if not menus[path][3].get_desktop_file_path():
if menu_id == menus[path][3].get_menu_id():
menu_tree = self.tree.get_object('menu_tree')
menu_tree.expand_to_path(path)
menu_tree.get_selection().select_path(path)
return True
return False
if os.path.split(menus[path][2].get_desktop_file_path())[1] == menu_id:
if os.path.split(menus[path][3].get_desktop_file_path())[1] == menu_id:
menu_tree = self.tree.get_object('menu_tree')
menu_tree.expand_to_path(path)
menu_tree.get_selection().select_path(path)
return True

def setupMenuTree(self):
self.menu_store = Gtk.TreeStore(GdkPixbuf.Pixbuf, str, object)
menus = self.tree.get_object('menu_tree')
column = Gtk.TreeViewColumn(_('Name'))
self.menu_store = Gtk.TreeStore(GdkPixbuf.Pixbuf, str, bool, object) # bool is unused, just a placeholder
menus = self.tree.get_object('menu_tree') # so object is the same index for
column = Gtk.TreeViewColumn(_('Name')) # the menu tree and item tree
column.set_spacing(4)
cell = Gtk.CellRendererPixbuf()
column.pack_start(cell, False)
@@ -200,7 +206,7 @@ class MainWindow(object):
name = "<small><i>%s</i></small>" % (name,)

icon = util.getIcon(menu)
iters[menu] = self.menu_store.append(iters[parent], (icon, name, menu))
iters[menu] = self.menu_store.append(iters[parent], (icon, name, False, menu))
self.loadMenu(iters, menu)

def loadItems(self, menu):
@@ -249,11 +255,11 @@ class MainWindow(object):
menu_tree = self.tree.get_object('menu_tree')
menus, iter = menu_tree.get_selection().get_selected()
if not iter:
parent = menus[(0,)][2]
parent = menus[(0,)][3]
menu_tree.expand_to_path((0,))
menu_tree.get_selection().select_path((0,))
else:
parent = menus[iter][2]
parent = menus[iter][3]
file_path = os.path.join(util.getUserDirectoryPath(), util.getUniqueFileId('alacarte-made', '.directory'))
process = subprocess.Popen(['gnome-desktop-item-edit', file_path], env=os.environ)
GObject.timeout_add(100, self.waitForNewMenuProcess, process, parent.get_menu_id(), file_path)
@@ -262,11 +268,11 @@ class MainWindow(object):
menu_tree = self.tree.get_object('menu_tree')
menus, iter = menu_tree.get_selection().get_selected()
if not iter:
parent = menus[(0,)][2]
parent = menus[(0,)][3]
menu_tree.expand_to_path((0,))
menu_tree.get_selection().select_path((0,))
else:
parent = menus[iter][2]
parent = menus[iter][3]
file_path = os.path.join(util.getUserItemPath(), util.getUniqueFileId('alacarte-made', '.desktop'))
process = subprocess.Popen(['gnome-desktop-item-edit', file_path], env=os.environ)
GObject.timeout_add(100, self.waitForNewItemProcess, process, parent.get_menu_id(), file_path)
@@ -285,7 +291,7 @@ class MainWindow(object):
self.editor.deleteSeparator(item)

def on_edit_properties_activate(self, menu):
item_tree = self.tree.get_object('item_tree')
item_tree = self.tree.get_object(self.last_tree)
items, iter = item_tree.get_selection().get_selected()
if not iter:
return
@@ -309,6 +315,43 @@ class MainWindow(object):
process = subprocess.Popen(['gnome-desktop-item-edit', file_path], env=os.environ)
GObject.timeout_add(100, self.waitForEditProcess, process, file_path)

def on_edit_cut_activate(self, menu):
item_tree = self.tree.get_object('item_tree')
items, iter = item_tree.get_selection().get_selected()
item = items[iter][3]
if not iter:
return
if not isinstance(item, GMenu.TreeEntry):
return
(self.cut_copy_buffer, self.file_id) = self.editor.cutItem(item)

def on_edit_copy_activate(self, menu):
item_tree = self.tree.get_object('item_tree')
items, iter = item_tree.get_selection().get_selected()
item = items[iter][3]
if not iter:
return
if not isinstance(item, GMenu.TreeEntry):
return
(self.cut_copy_buffer, self.file_id) = self.editor.copyItem(item)

def on_edit_paste_activate(self, menu):
item_tree = self.tree.get_object('item_tree')
items, iter = item_tree.get_selection().get_selected()
if not iter:
menu_tree = self.tree.get_object('menu_tree')
items, iter = menu_tree.get_selection().get_selected()
if not iter:
return
item = items[iter][3]
if not isinstance(item, GMenu.TreeDirectory):
return
if self.cut_copy_buffer is not None:
success = self.editor.pasteItem(self.cut_copy_buffer, item, self.file_id)
if success:
self.cut_copy_buffer = None
self.file_id = None

def on_menu_tree_cursor_changed(self, treeview):
selection = treeview.get_selection()
if selection is None:
@@ -316,16 +359,34 @@ class MainWindow(object):
menus, iter = selection.get_selected()
if iter is None:
return
menu = menus[iter][3]

menu_path = menus.get_path(iter)

item_tree = self.tree.get_object('item_tree')
item_tree.get_selection().unselect_all()
self.loadItems(self.menu_store[menu_path][2])
self.loadItems(self.menu_store[menu_path][3])
self.tree.get_object('edit_delete').set_sensitive(False)
self.tree.get_object('edit_properties').set_sensitive(False)
self.tree.get_object('move_up_button').set_sensitive(False)
self.tree.get_object('move_down_button').set_sensitive(False)
self.tree.get_object('properties_button').set_sensitive(False)
self.tree.get_object('edit_properties').set_sensitive(True)
self.tree.get_object('edit_cut').set_sensitive(False)
self.tree.get_object('edit_copy').set_sensitive(False)
self.tree.get_object('properties_button').set_sensitive(True)
self.tree.get_object('delete_button').set_sensitive(False)
self.tree.get_object('cut_button').set_sensitive(False)
self.tree.get_object('copy_button').set_sensitive(False)

can_paste = isinstance(menu, GMenu.TreeDirectory) and self.cut_copy_buffer is not None
self.tree.get_object('edit_paste').set_sensitive(can_paste)
self.tree.get_object('paste_button').set_sensitive(can_paste)

index = menus.get_path(iter).get_indices()[menus.get_path(iter).get_depth() - 1]
parent_iter = menus.iter_parent(iter)
count = menus.iter_n_children(parent_iter)
can_go_up = index > 0 and isinstance(menu, GMenu.TreeDirectory)
can_go_down = index < count - 1 and isinstance(menu, GMenu.TreeDirectory)
self.tree.get_object('move_up_button').set_sensitive(can_go_up)
self.tree.get_object('move_down_button').set_sensitive(can_go_down)
self.last_tree = "menu_tree"

def on_item_tree_show_toggled(self, cell, path):
item = self.item_store[path][3]
@@ -353,11 +414,23 @@ class MainWindow(object):
self.tree.get_object('edit_properties').set_sensitive(can_edit)
self.tree.get_object('properties_button').set_sensitive(can_edit)

can_cut_copy = not isinstance(item, GMenu.TreeDirectory)
self.tree.get_object('cut_button').set_sensitive(can_cut_copy)
self.tree.get_object('copy_button').set_sensitive(can_cut_copy)
self.tree.get_object('edit_cut').set_sensitive(can_cut_copy)
self.tree.get_object('edit_copy').set_sensitive(can_cut_copy)

can_paste = isinstance(item, GMenu.TreeDirectory) and self.cut_copy_buffer is not None

self.tree.get_object('edit_paste').set_sensitive(can_paste)
self.tree.get_object('paste_button').set_sensitive(can_paste)

index = items.get_path(iter).get_indices()[0]
can_go_up = index > 0 and isinstance(item, GMenu.TreeDirectory)
can_go_down = index < len(items) - 1 and isinstance(item, GMenu.TreeDirectory)
self.tree.get_object('move_up_button').set_sensitive(can_go_up)
self.tree.get_object('move_down_button').set_sensitive(can_go_down)
self.last_tree = "item_tree"

def on_item_tree_row_activated(self, treeview, path, column):
self.on_edit_properties_activate(None)
@@ -386,34 +459,53 @@ class MainWindow(object):
#without this shift-f10 won't work
return True

def on_menu_tree_popup_menu(self, menu_tree, event=None):
model, iter = menu_tree.get_selection().get_selected()
if event:
#don't show if it's not the right mouse button
if event.button != 3:
return
button = event.button
event_time = event.time
info = menu_tree.get_path_at_pos(int(event.x), int(event.y))
if info is not None:
path, col, cellx, celly = info
menu_tree.grab_focus()
menu_tree.set_cursor(path, col, 0)
else:
path = model.get_path(iter)
button = 0
event_time = 0
menu_tree.grab_focus()
menu_tree.set_cursor(path, menu_tree.get_columns()[0], 0)
popup = self.tree.get_object('edit_menu')
popup.popup(None, None, None, None, button, event_time)
#without this shift-f10 won't work
return True

def on_item_tree_key_press_event(self, item_tree, event):
if event.keyval == Gdk.KEY_Delete:
self.on_edit_delete_activate(item_tree)

def on_move_up_button_clicked(self, button):
item_tree = self.tree.get_object('item_tree')
item_tree = self.tree.get_object(self.last_tree)
items, iter = item_tree.get_selection().get_selected()
if not iter:
return
path = items.get_path(iter)
#at top, can't move up
if path.get_indices()[0] == 0:
return
item = items[path][3]
before = items[(path.get_indices()[0] - 1,)][3]

item = items[iter][3]
before = items[items.iter_previous(iter)][3]

self.editor.moveItem(item.get_parent(), item, before=before)

def on_move_down_button_clicked(self, button):
item_tree = self.tree.get_object('item_tree')
item_tree = self.tree.get_object(self.last_tree)
items, iter = item_tree.get_selection().get_selected()
if not iter:
return
path = items.get_path(iter)
#at bottom, can't move down
if path.get_indices()[0] == (len(items) - 1):
return
item = items[path][3]
after = items[path][3]

item = items[iter][3]
after = items[iter][3]
self.editor.moveItem(item.get_parent(), item, after=after)

def on_restore_button_clicked(self, button):
@@ -424,8 +516,18 @@ class MainWindow(object):

def on_properties_button_clicked(self, button):
self.on_edit_properties_activate(None)

def on_delete_button_clicked(self, button):
self.on_edit_delete_activate(None)

def on_cut_button_clicked(self, button):
self.on_edit_cut_activate(None)

def on_copy_button_clicked(self, button):
self.on_edit_copy_activate(None)

def on_paste_button_clicked(self, button):
self.on_edit_paste_activate(None)

def quit(self):
Gtk.main_quit()

+ 40
- 18
files/usr/lib/cinnamon-menu-editor/cme/MenuEditor.py View File

@@ -241,33 +241,47 @@ class MenuEditor(object):
self.addXmlTextElement(menu_xml, 'DirectoryDir', util.getUserDirectoryPath(), dom)
self.save()

def copyItem(self, item, new_parent, before=None, after=None):
def copyItem(self, item):
dom = self.dom
file_path = item.get_desktop_file_path()
keyfile = GLib.KeyFile()
keyfile.load_from_file(file_path, util.KEY_FILE_FLAGS)
copy_buffer = GLib.KeyFile()
copy_buffer.load_from_file(file_path, util.KEY_FILE_FLAGS)
return (copy_buffer, None)

util.fillKeyFile(keyfile, dict(Categories=[], Hidden=False))
def cutItem(self, item):
copy_buffer, file_id = self.copyItem(item)
file_id = self.deleteItem(item)
return (copy_buffer, file_id)

app_info = item.get_app_info()
file_id = util.getUniqueFileId(app_info.get_name().replace(os.sep, '-'), '.desktop')
out_path = os.path.join(util.getUserItemPath(), file_id)
def pasteItem(self, cut_copy_buffer, menu, file_id = None):
try:
path = self.getPath(menu)
util.fillKeyFile(cut_copy_buffer, dict(Hidden=False, NoDisplay=False))
name = util.getNameFromKeyFile(cut_copy_buffer)
if file_id is None:
file_id = util.getUniqueFileId(name.replace(os.sep, '-'), '.desktop')
out_path = os.path.join(util.getUserItemPath(), file_id)
contents, length = cut_copy_buffer.to_data()
f = open(out_path, 'w')
f.write(contents)
f.close()
menu_xml = self.getXmlMenu(path, self.dom.documentElement, self.dom)
self.addXmlFilename(menu_xml, self.dom, file_id, 'Include')
self.addXmlTextElement(menu_xml, 'AppDir', util.getUserItemPath(), self.dom)
self.save()
return True
except:
return False

contents, length = keyfile.to_data()
def deleteItem(self, item):
file_id = self.writeItem(item, Hidden=True)
item_xml = self.getXmlMenu(self.getPath(item.get_parent()), self.dom.documentElement, self.dom)

f = open(out_path, 'w')
f.write(contents)
f.close()
self.removeXmlFilename(item_xml, self.dom, file_id)

self.addItem(new_parent, file_id, dom)
self.positionItem(new_parent, ('Item', file_id), before, after)
self.save()
return file_id

def deleteItem(self, item):
self.writeItem(item, Hidden=True)
self.save()

def deleteMenu(self, menu):
dom = self.dom
menu_xml = self.getXmlMenu(self.getPath(menu), dom.documentElement, dom)
@@ -315,7 +329,10 @@ class MenuEditor(object):
names = []
current = menu
while current is not None:
names.append(current.get_menu_id())
try:
names.append(current.get_menu_id())
except:
names.append(current.get_desktop_file_id())
current = current.get_parent()

# XXX - don't append root menu name, alacarte doesn't
@@ -365,6 +382,11 @@ class MenuEditor(object):
node.appendChild(self.addXmlTextElement(node, 'Filename', filename, dom))
return element.appendChild(node)

def removeXmlFilename(self, element, dom, filename):
for node in self.getXmlNodesByName(['Include'], element):
if node.childNodes[0].nodeName == 'Filename' and node.childNodes[0].childNodes[0].nodeValue == filename:
element.removeChild(node)

def addDeleted(self, element, dom):
node = dom.createElement('Deleted')
return element.appendChild(node)


+ 3
- 0
files/usr/lib/cinnamon-menu-editor/cme/util.py View File

@@ -37,6 +37,9 @@ def fillKeyFile(keyfile, items):
elif isinstance(item, basestring):
keyfile.set_string(DESKTOP_GROUP, key, item)

def getNameFromKeyFile(keyfile):
return keyfile.get_string(DESKTOP_GROUP, "Name")

def getUniqueFileId(name, extension):
while 1:
filename = name + '-' + str(uuid.uuid1()) + extension


+ 5
- 1
files/usr/lib/cinnamon-screensaver-lock-dialog/cinnamon-screensaver-lock-dialog.py View File

@@ -55,7 +55,11 @@ class MainWindow:
self.window.show()
def lock_screen(self, data):
os.system("cinnamon-screensaver-command --lock --away-message \"%s\" &" % self.entry.get_text())
message = self.entry.get_text()
if (message != ""):
os.system("cinnamon-screensaver-command --lock --away-message \"%s\" &" % self.entry.get_text())
else:
os.system("cinnamon-screensaver-command --lock &")
gtk.main_quit()
if __name__ == "__main__":


+ 1223
- 0
files/usr/lib/cinnamon-settings/bin/ExtensionCore.py
File diff suppressed because it is too large
View File


+ 23
- 8
files/usr/lib/cinnamon-settings/bin/SettingsWidgets.py View File

@@ -29,7 +29,7 @@ except Exception, detail:
sys.exit(1)

class SidePage:
def __init__(self, name, icon, keywords, advanced, content_box, is_c_mod = False, is_standalone = False, exec_name = None):
def __init__(self, name, icon, keywords, advanced, content_box, size = None, is_c_mod = False, is_standalone = False, exec_name = None):
self.name = name
self.icon = icon
self.content_box = content_box
@@ -39,6 +39,7 @@ class SidePage:
self.exec_name = exec_name
self.keywords = keywords
self.advanced = advanced
self.size = size
self.topWindow = None
self.builder = None

@@ -54,7 +55,7 @@ class SidePage:
# Add our own widgets
# C modules are sort of messy - they check the desktop type
# (for Unity or GNOME) and show/hide UI items depending on
# the result - so we can't just show_all on the widget, it will
# the result - so we cannot just show_all on the widget, it will
# mess up these modifications - so for these, we just show the
# top-level widget
if not self.is_standalone:
@@ -85,7 +86,7 @@ class SidePage:

class CCModule:
def __init__(self, label, mod_id, icon, category, advanced, keywords, content_box):
sidePage = SidePage(label, icon, keywords, advanced, content_box, True, False, mod_id)
sidePage = SidePage(label, icon, keywords, advanced, content_box, False, True, False, mod_id)
self.sidePage = sidePage
self.name = mod_id
self.category = category
@@ -102,7 +103,7 @@ class CCModule:

class SAModule:
def __init__(self, label, mod_id, icon, category, advanced, keywords, content_box):
sidePage = SidePage(label, icon, keywords, advanced, content_box, False, True, mod_id)
sidePage = SidePage(label, icon, keywords, advanced, content_box, False, False, True, mod_id)
self.sidePage = sidePage
self.name = mod_id
self.category = category
@@ -154,6 +155,9 @@ class IndentedHBox(Gtk.HBox):
def add(self, item):
self.pack_start(item, False, False, 0)

def add_expand(self, item):
self.pack_start(item, True, True, 0)

class GSettingsCheckButton(Gtk.CheckButton):
def __init__(self, label, schema, key, dep_key):
self.key = key
@@ -427,6 +431,7 @@ class GSettingsRange(Gtk.HBox):
self.dep_key = dep_key
self.settings = Gio.Settings.new(schema)
self.valtype = valtype

if self.valtype == "int":
self.value = self.settings.get_int(self.key) * 1.0
elif self.valtype == "uint":
@@ -434,8 +439,14 @@ class GSettingsRange(Gtk.HBox):
elif self.valtype == "double":
self.value = self.settings.get_double(self.key) * 1.0
self.label = Gtk.Label(label)
self.label.set_alignment(1.0, 0.5)
self.label.set_size_request(100, -1)
self.low_label = Gtk.Label()
self.low_label.set_alignment(0.5, 0.5)
self.low_label.set_size_request(60, -1)
self.hi_label = Gtk.Label()
self.hi_label.set_alignment(0.5, 0.5)
self.hi_label.set_size_request(60, -1)
self.low_label.set_markup("<i><small>%s</small></i>" % low_label)
self.hi_label.set_markup("<i><small>%s</small></i>" % hi_label)
self.inverted = inverted
@@ -445,15 +456,19 @@ class GSettingsRange(Gtk.HBox):
self._min = low_limit * 1.0
self._max = hi_limit * 1.0
self.content_widget = Gtk.Scale.new_with_range(Gtk.Orientation.HORIZONTAL, 0, 1, (self._step / self._range))
self.content_widget.set_size_request(300, 0)
self.content_widget.set_value(self.to_corrected(self.value))
self.content_widget.set_draw_value(False);

self.grid = Gtk.Grid()
if (label != ""):
self.pack_start(self.label, False, False, 2)
self.grid.attach(self.label, 0, 0, 1, 1)
if (low_label != ""):
self.pack_start(self.low_label, False, False, 2)
self.pack_start(self.content_widget, True, True, 2)
self.grid.attach(self.low_label, 1, 0, 1, 1)
self.grid.attach(self.content_widget, 2, 0, 1, 1)
if (hi_label != ""):
self.pack_start(self.hi_label, False, False, 2)
self.grid.attach(self.hi_label, 3, 0, 1, 1)
self.pack_start(self.grid, True, True, 2)
self._dragging = False
self.content_widget.connect('value-changed', self.on_my_value_changed)
self.content_widget.connect('button-press-event', self.on_mouse_down)


+ 297
- 141
files/usr/lib/cinnamon-settings/bin/Spices.py View File

@@ -3,14 +3,14 @@ try:
import gettext
from gi.repository import Gio, Gtk, GObject, Gdk, GdkPixbuf
# WebKit requires gir1.2-javascriptcoregtk-3.0 and gir1.2-webkit-3.0
try:
from gi.repository import WebKit