diff options
| author | Didier Roche <didier.roche@canonical.com> | 2011-01-14 20:15:45 +0100 |
|---|---|---|
| committer | Didier Roche <didier.roche@canonical.com> | 2011-01-14 20:15:45 +0100 |
| commit | 594d5035bed8e3538d46af2ff35ba85bfa7e129a (patch) | |
| tree | 41a1c670390f5ae1356b14c7d7da4e7a253c3c18 | |
| parent | 4b8db9985fddc96d52e2b181c46acb15eacb2d92 (diff) | |
| parent | 36f064ea7607c5736771b5603cb03db84153bdb7 (diff) | |
Import upstream version 3.2.12upstream-3.2.12
(bzr r55.4.38)
139 files changed, 4827 insertions, 686 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index e6253eac3..9965df4f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,9 @@ project (unity) cmake_minimum_required(VERSION 2.8) -subdirs (libunity services tests tools) +include (cmake/Documentation.cmake) + +subdirs (libunity services tests tools doc) # # Base bits @@ -9,7 +11,7 @@ subdirs (libunity services tests tools) set (PROJECT_NAME "unity") set (UNITY_MAJOR 3) set (UNITY_MINOR 2) -set (UNITY_MICRO 8) +set (UNITY_MICRO 12) set (UNITY_VERSION "${UNITY_MAJOR}.${UNITY_MINOR}.${UNITY_MICRO}") set (UNITY_API_VERSION "3.0") @@ -85,13 +87,13 @@ endif (BOOT_LOGGER) # # src (Compiz Plugin) # -set (UNITY_PLUGIN_DEPS "nux-0.9;libbamf;dbus-glib-1;dee-1.0;gee-1.0;gio-2.0;gio-unix-2.0;dbusmenu-glib;x11;libstartup-notification-1.0;gthread-2.0;indicator") +set (UNITY_PLUGIN_DEPS "nux-0.9;libbamf;dbus-glib-1;dee-1.0;gee-1.0;gio-2.0;gio-unix-2.0;dbusmenu-glib-0.4;x11;libstartup-notification-1.0;gthread-2.0;indicator;atk") find_package (Compiz REQUIRED) include (CompizPlugin) compiz_plugin (unityshell PKGDEPS ${UNITY_PLUGIN_DEPS} - PLUGINDEPS composite opengl scale + PLUGINDEPS composite opengl CFLAGSADD "-DINSTALLPREFIX='\"${CMAKE_INSTALL_PREFIX}\"' -DPKGDATADIR='\"${CMAKE_INSTALL_PREFIX}/share/unity/3\"' -I${CMAKE_BINARY_DIR} ${BOOT_LOGGER_FLAG}" LIBRARIES "unity" ) @@ -28,7 +28,7 @@ libglib2.0-dev libgdk-pixbuf2.0-dev libcairo2-dev libpng12-dev libglew1.5-dev libglewmx1.5-dev libxxf86vm-dev libgl1-mesa-dev libsigc++-2.0-dev - libpango1.0-dev doxygen cmake pkg-config valac intltool libgee-dev + libpango1.0-dev doxygen cmake pkg-config valac-0.12 intltool libgee-dev libbamf-dev gsettings-desktop-schemas-dev libgconf2-dev libglib2.0-dev libdbusmenu-glib-dev libgtk2.0-dev libdee-dev libindicator-dev libboost-dev libboost-serialization-dev libmetacity-dev python-dev cython diff --git a/cmake/Documentation.cmake b/cmake/Documentation.cmake new file mode 100644 index 000000000..55c908c5c --- /dev/null +++ b/cmake/Documentation.cmake @@ -0,0 +1,111 @@ +# Copyright (C) 2009 Julian Andres Klode <jak@debian.org>. +# Licensed under the same terms as APT; i.e. GPL 2 or later. + +macro(add_debiandoc target sourcefiles installdest) + foreach(file ${sourcefiles}) + get_filename_component(relfile ${file} NAME) + string(REPLACE ".sgml" "" manual ${relfile}) + get_filename_component(absolute ${file} ABSOLUTE) + + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${manual}.html + COMMAND debiandoc2html ${absolute} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${file} + ) + set(commands ${commands} ${CMAKE_CURRENT_BINARY_DIR}/${manual}.html) + if (NOT ${installdest} EQUAL "" ) + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${manual}.html + DESTINATION ${installdest}) + endif (NOT ${installdest} EQUAL "" ) + endforeach(file ${sourcefiles}) + + add_custom_target(${target} ALL DEPENDS ${commands}) +endmacro(add_debiandoc target sourcefiles installdest) + + +macro(add_po4a type master po target deps) + add_custom_command(OUTPUT ${target} + COMMAND po4a-translate --keep 0 -f ${type} -m ${master} + -p ${po} -l ${target} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${deps} ${master} ${po}) +endmacro(add_po4a type master po target deps) + + +# Macro for XML man pages. +macro(add_xml_manpages target manpages translations entities) + foreach(manpage ${manpages}) + string(LENGTH ${manpage} manpage_length) + math(EXPR manpage_length ${manpage_length}-1) + string(SUBSTRING ${manpage} ${manpage_length} 1 section) + + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${manpage} + COMMAND xmlto man ${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.xml + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${manpage}.xml + ) + + + set(commands ${commands} ${CMAKE_CURRENT_BINARY_DIR}/${manpage}) + + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${manpage} + DESTINATION share/man/man${section}) + + # Add the translations for the manpage. + foreach(translation ${translations}) + set(entities) + # transdir = shortcut to the output directory for translations. + set(transdir ${CMAKE_CURRENT_BINARY_DIR}/${translation}) + + foreach(entity ${entities}) + add_custom_command(OUTPUT ${transdir}/${entity} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory ${transdir} + COMMAND ${CMAKE_COMMAND} -E copy ${entity} ${transdir}) + set(ent_cmds ${ent_cmds} ${transdir}/${entity}) + endforeach(entity ${entities}) + + + + add_po4a(docbook ${manpage}.xml po/${translation}.po + ${transdir}/${manpage}.xml "${ent_cmds}") + + + add_custom_command(OUTPUT ${transdir}/${manpage} + COMMAND xmlto -o ${transdir} man ${transdir}/${manpage}.xml + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${transdir}/${manpage}.xml) + + set(nls-cmd ${nls-cmd} ${transdir}/${manpage}) + install(FILES ${transdir}/${manpage} + DESTINATION share/man/${translation}/man${section}) + + endforeach(translation ${translations}) + endforeach(manpage ${manpages}) + + add_custom_target(${target} ALL DEPENDS ${commands}) + # Sort the list of the translations. + list(SORT nls-cmd) + add_custom_target(nls-${target} ALL DEPENDS ${nls-cmd}) +endmacro(add_xml_manpages manpages) + + +macro(add_manpages target manpages translations) + foreach(man ${manpages}) + string(LENGTH ${man} manpage_length) + math(EXPR manpage_length ${manpage_length}-1) + string(SUBSTRING ${man} ${manpage_length} 1 section) + install(FILES ${man} DESTINATION share/man/man${section}) + + if (USE_NLS) + foreach(translation ${translations}) + set(transdir ${CMAKE_CURRENT_BINARY_DIR}/${translation}) + add_po4a(man ${man} po/${translation}.po ${transdir}/${man} "") + install(FILES ${transdir}/${man} + DESTINATION share/man/${translation}/man${section}) + set(files ${files} ${transdir}/${man}) + endforeach(translation ${translations}) + endif(USE_NLS) + endforeach(man ${manpages}) + add_custom_target(${target} ALL DEPENDS ${files}) +endmacro(add_manpages target manpages translations) diff --git a/cmake/vala/FindVala.cmake b/cmake/vala/FindVala.cmake index aa3a6e7d2..3086259b0 100644 --- a/cmake/vala/FindVala.cmake +++ b/cmake/vala/FindVala.cmake @@ -45,7 +45,7 @@ # Search for the valac executable in the usual system paths. find_program(VALA_EXECUTABLE - NAMES valac) + NAMES valac-0.12) # Handle the QUIETLY and REQUIRED arguments, which may be given to the find call. # Furthermore set VALA_FOUND to TRUE if Vala has been found (aka. diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 000000000..e8a40c570 --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,3 @@ +set(manpages "unity.1;unity-panel-service.1") + +add_manpages(doc-rawman "${manpages}" "fr;") diff --git a/doc/fr/unity-panel-service.fr.1 b/doc/fr/unity-panel-service.fr.1 new file mode 100644 index 000000000..af88d9f61 --- /dev/null +++ b/doc/fr/unity-panel-service.fr.1 @@ -0,0 +1,28 @@ +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH unity\-panel\-service 1 "8 DĆ©cembre 2010" "" "Manuel de l'utilisateur Linux" + +.SH NOM +unity\-panel\-service \- programme pour l'affichage du paneau dans le shell +Unity. + +.SH SYNOPSIS +\fBunity\-panel\-service\fP +.br + +.SH DESCRIPTION +Le programme \fBunity\-panel\-service\fP est automatiquement dĆ©marrĆ© par le +shell Unity (qui est dĆ©marrĆ© en tant que module Compiz) et est utilisĆ© +pour peindre Ć l'Ć©cran les paneaux qui sont utilisĆ©s pour afficher le +menu global, ou alors pour contenir les indicateurs. + +.SH OPTIONS +\fBunity\-panel\-service\fP n'attend pas d'options. + +.SH NOTES + +.SH "VOIR AUSSI" + diff --git a/doc/fr/unity.fr.1 b/doc/fr/unity.fr.1 new file mode 100644 index 000000000..cc64cc7ce --- /dev/null +++ b/doc/fr/unity.fr.1 @@ -0,0 +1,41 @@ +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH unity 1 "9 December 2010" "" "Manuel de l'utilisateur Linux" + +.SH NOM +unity \- script pour dmarrer et contrler le shell Unity + +.SH SYNOPSIS +\fBunity\fP [\fIoptions\fP] +.br + +.SH DESCRIPTION +Le programme \fBunity\fP peut tre utilis afin de dmarrer le shell Unity ainsi +que pour configurer les paramtres de log, dboguage, et comment agir avec le +profile utilisateur. + +.SH OPTIONS +.IP \fB\-\-advanced\-debug\fP +Dmarre unity avec les options de dboguage (en utilisant GDB ou un autre +outil cet effet) pour aider les dveloppeurs indentifier des problmes dans +le but de complter un rapport de bogue. + +.IP \fB\-\-log\fP \<filename\> +Ce paramtre, suivi d'un chemin d'accs ou du nom d'un fichier, prcise o le +shell Unity doit crire les logs. + +.IP \fB\-\-reset\fP +Cette option permet l'utilisateur de rinitialiser son profile et remettre +zro les paramtres dans compiz. + +.IP \fB\-\-verbose\fP +Cette option active l'affichage d'informations supplmentaires pour le shell +Unity. Elle peut tre utilise par l'utilisateur pour dceler des problmes de +configuration. Cette option est souvent utilise avec \fB\-\-log\fP pour +enregistrer la sortie dans un fichier. + +.SH "VOIR AUSSI" +\fBunity\-panel\-service\fP (1) diff --git a/doc/makefile b/doc/makefile new file mode 100644 index 000000000..fff97a9bf --- /dev/null +++ b/doc/makefile @@ -0,0 +1,15 @@ +#!/usr/bin/make + +doc: po4a + +clean: po4a-clean + +.PHONY: update-po po4a +update-po: + po4a --previous --no-backups --force --no-translations po4a.conf + +po4a-clean: + po4a --previous --rm-backups --rm-translations po4a.conf + +po4a: + po4a --previous --no-backups po4a.conf diff --git a/doc/po/fr.po b/doc/po/fr.po new file mode 100644 index 000000000..ddc7b658e --- /dev/null +++ b/doc/po/fr.po @@ -0,0 +1,189 @@ +#. type: TH +#: unity.1:1 +#, no-wrap +msgid "unity" +msgstr "unity" + +#. type: TH +#: unity.1:1 +#, no-wrap +msgid "9 December 2010" +msgstr "" + +#. type: TH +#: unity.1:1 unity-panel-service.1:1 +#, no-wrap +msgid "Linux User's Manual" +msgstr "Manuel de l'utilisateur Linux" + +#. type: SH +#: unity.1:3 unity-panel-service.1:3 +#, no-wrap +msgid "NAME" +msgstr "NOM" + +#. type: Plain text +#: unity.1:5 +msgid "unity - wrapper for starting the unity shell and handling fallback" +msgstr "unity - script pour dĆ©marrer et contrĆ“ler le shell Unity" + +#. type: SH +#: unity.1:6 unity-panel-service.1:6 +#, no-wrap +msgid "SYNOPSIS" +msgstr "SYNOPSIS" + +#. type: Plain text +#: unity.1:9 +msgid "B<unity> [I<options>]" +msgstr "B<unity> [I<options>]" + +#. type: SH +#: unity.1:11 unity-panel-service.1:10 +#, no-wrap +msgid "DESCRIPTION" +msgstr "DESCRIPTION" + +#. type: Plain text +#: unity.1:13 +msgid "" +"The B<unity> program can be used to start the Unity shell as a compiz " +"module, and to specify how to handle logging, debugging, as well as how to " +"deal with the user's profile." +msgstr "" +"Le programme B<unity> peut ĆŖtre utilisĆ© afin de dĆ©marrer le shell Unity " +"ainsi que pour configurer les paramĆØtres de log, dĆ©boguage, et comment agir " +"avec le profile utilisateur." + +#. type: SH +#: unity.1:14 unity-panel-service.1:13 +#, no-wrap +msgid "OPTIONS" +msgstr "OPTIONS" + +#. type: IP +#: unity.1:15 +#, no-wrap +msgid "B<--advanced-debug>" +msgstr "B<--advanced-debug>" + +#. type: Plain text +#: unity.1:17 +msgid "" +"Runs unity under debugging (using GDB or another debugger tool) to help " +"tracking issues. Should only be used on request from a developper following " +"a bug report." +msgstr "" +"DĆ©marre unity avec les options de dĆ©boguage (en utilisant GDB ou un autre " +"outil Ć cet effet) pour aider les dĆ©veloppeurs Ć identifier des " +"problĆØmes dans le but de complĆ©ter un rapport de bogue." + +#. type: IP +#: unity.1:18 +#, no-wrap +msgid "B<--log>\\ I<filename>" +msgstr "B<--log>\\ I<ficher>" + +#. type: Plain text +#: unity.1:20 +msgid "" +"This parameter, followed by a path or filename, tells the Unity shell to " +"store logs in the specified file." +msgstr "" +"Ce paramĆØtre, suivi d'un chemin d'accĆØs ou du nom d'un fichier, prĆ©cise où " +"le shell Unity doit Ć©crire les logs." + +#. type: IP +#: unity.1:21 +#, no-wrap +msgid "B<--reset>" +msgstr "B<--reset>" + +#. type: Plain text +#: unity.1:23 +msgid "" +"This option allows the user to reset profile parameters in compiz and " +"restart the Unity shell with default settings." +msgstr "" +"Cette option permet Ć l'utilisateur de rĆ©initialiser son profile et " +"remettre Ć zĆ©ro les paramĆØtres de compiz." + +#. type: IP +#: unity.1:24 +#, no-wrap +msgid "B<--verbose>" +msgstr "B<--verbose>" + +#. type: Plain text +#: unity.1:26 +msgid "" +"This option turns on displaying additional debugging output for the Unity " +"shell. It can be used by the user to debug configuration issues. This option " +"is often used along with the B<--log> option to save output to a file." +msgstr "" +"Cette option active l'affichage d'informations supplĆ©mentaires pour le shell " +"Unity. Elle peut ĆŖtre utilisĆ©e par l'utilisateur pour dĆ©celer des problĆØmes " +"de configuration. Cette option est souvent utilisĆ©e avec B<--log> pour " +"enregistrer la sortie dans un fichier." + +#. type: SH +#: unity.1:27 unity-panel-service.1:18 +#, no-wrap +msgid "SEE ALSO" +msgstr "VOIR AUSSI" + +#. type: Plain text +#: unity.1:29 +msgid "B<unity-panel-service> (1)" +msgstr "B<unity-panel-service> (1)" + +#. type: TH +#: unity-panel-service.1:1 +#, no-wrap +msgid "unity-panel-service" +msgstr "unity-panel-service" + +#. type: TH +#: unity-panel-service.1:1 +#, no-wrap +msgid "8 December 2010" +msgstr "8 DĆ©cembre 2010" + +#. type: Plain text +#: unity-panel-service.1:5 +msgid "" +"unity-panel-service - program for drawing the panel with the unity shell." +msgstr "" +"unity-panel-service - programme pour l'affichage du panneau dans le shell " +"Unity." + +#. type: Plain text +#: unity-panel-service.1:8 +msgid "B<unity-panel-service>" +msgstr "B<unity-panel-service>" + +#. type: Plain text +#: unity-panel-service.1:12 +msgid "" +"The B<unity-panel-service> program is normally started automatically by the " +"Unity shell (which gets started as a compiz module) and is used to draw " +"panels which can then be used for the global menu, or to hold indicators." +msgstr "" +"Le programme B<unity-panel-service> est automatiquement dĆ©marrĆ© par le " +"shell Unity (qui est dĆ©marrĆ© en tant que module Compiz) et est utilisĆ© " +"pour peindre Ć l'Ć©cran les panneaux qui sont utilisĆ©s pour afficher le " +"menu global, ou alors pour contenir les indicateurs." + +#. type: Plain text +#: unity-panel-service.1:15 +msgid "B<unity-panel-service> takes no options." +msgstr "B<unity-panel-service> n'attend pas d'options." + +#. type: SH +#: unity-panel-service.1:16 +#, no-wrap +msgid "NOTES" +msgstr "NOTES" + +#~ msgid "B<--log>" +#~ msgstr "B<--log>" diff --git a/doc/po/unity-doc.pot b/doc/po/unity-doc.pot new file mode 100644 index 000000000..a0bf8a25e --- /dev/null +++ b/doc/po/unity-doc.pot @@ -0,0 +1,182 @@ +# Translation template for Unity documentation pages. +# Copyright (C) 2010 Canonical Ltd. +# This file is distributed under the same license as the Unity package. +# Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>, 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2010-12-23 10:48-0500\n" +"PO-Revision-Date: 2010-12-23 10:56-0500\n" +"Last-Translator: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: TH +#: unity.1:1 +#, no-wrap +msgid "unity" +msgstr "" + +#. type: TH +#: unity.1:1 +#, no-wrap +msgid "9 December 2010" +msgstr "" + +#. type: TH +#: unity.1:1 unity-panel-service.1:1 +#, no-wrap +msgid "Linux User's Manual" +msgstr "" + +#. type: SH +#: unity.1:3 unity-panel-service.1:3 +#, no-wrap +msgid "NAME" +msgstr "" + +#. type: Plain text +#: unity.1:5 +msgid "unity - wrapper for starting the unity shell and handling fallback" +msgstr "" + +#. type: SH +#: unity.1:6 unity-panel-service.1:6 +#, no-wrap +msgid "SYNOPSIS" +msgstr "" + +#. type: Plain text +#: unity.1:9 +msgid "B<unity> [I<options>]" +msgstr "" + +#. type: SH +#: unity.1:11 unity-panel-service.1:10 +#, no-wrap +msgid "DESCRIPTION" +msgstr "" + +#. type: Plain text +#: unity.1:13 +msgid "" +"The B<unity> program can be used to start the Unity shell as a compiz " +"module, and to specify how to handle logging, debugging, as well as how to " +"deal with the user's profile." +msgstr "" + +#. type: SH +#: unity.1:14 unity-panel-service.1:13 +#, no-wrap +msgid "OPTIONS" +msgstr "" + +#. type: IP +#: unity.1:15 +#, no-wrap +msgid "B<--advanced-debug>" +msgstr "" + +#. type: Plain text +#: unity.1:17 +msgid "" +"Runs unity under debugging (using GDB or another debugger tool) to help " +"tracking issues. Should only be used on request from a developper following " +"a bug report." +msgstr "" + +#. type: IP +#: unity.1:18 +#, no-wrap +msgid "B<--log>\\ I<filename>" +msgstr "" + +#. type: Plain text +#: unity.1:20 +msgid "" +"This parameter, followed by a path or filename, tells the Unity shell to " +"store logs in the specified file." +msgstr "" + +#. type: IP +#: unity.1:21 +#, no-wrap +msgid "B<--reset>" +msgstr "" + +#. type: Plain text +#: unity.1:23 +msgid "" +"This option allows the user to reset profile parameters in compiz and " +"restart the Unity shell with default settings." +msgstr "" + +#. type: IP +#: unity.1:24 +#, no-wrap +msgid "B<--verbose>" +msgstr "" + +#. type: Plain text +#: unity.1:26 +msgid "" +"This option turns on displaying additional debugging output for the Unity " +"shell. It can be used by the user to debug configuration issues. This option " +"is often used along with the B<--log> option to save output to a file." +msgstr "" + +#. type: SH +#: unity.1:27 unity-panel-service.1:18 +#, no-wrap +msgid "SEE ALSO" +msgstr "" + +#. type: Plain text +#: unity.1:29 +msgid "B<unity-panel-service> (1)" +msgstr "" + +#. type: TH +#: unity-panel-service.1:1 +#, no-wrap +msgid "unity-panel-service" +msgstr "" + +#. type: TH +#: unity-panel-service.1:1 +#, no-wrap +msgid "8 December 2010" +msgstr "" + +#. type: Plain text +#: unity-panel-service.1:5 +msgid "unity-panel-service - program for drawing the panel with the unity shell." +msgstr "" + +#. type: Plain text +#: unity-panel-service.1:8 +msgid "B<unity-panel-service>" +msgstr "" + +#. type: Plain text +#: unity-panel-service.1:12 +msgid "" +"The B<unity-panel-service> program is normally started automatically by the " +"Unity shell (which gets started as a compiz module) and is used to draw " +"panels which can then be used for the global menu, or to hold indicators." +msgstr "" + +#. type: Plain text +#: unity-panel-service.1:15 +msgid "B<unity-panel-service> takes no options." +msgstr "" + +#. type: SH +#: unity-panel-service.1:16 +#, no-wrap +msgid "NOTES" +msgstr "" diff --git a/doc/po4a.conf b/doc/po4a.conf new file mode 100644 index 000000000..ecd43e55f --- /dev/null +++ b/doc/po4a.conf @@ -0,0 +1,9 @@ +# location of pot and po +[po_directory] po + +# Entities need to be present, even if not translated +[po4a_alias:entity] text opt:"-k 0" + +# define source file and translated file (one file per line) +[type: man] unity.1 $lang:$lang/unity.$lang.1 +[type: man] unity-panel-service.1 $lang:$lang/unity-panel-service.$lang.1 diff --git a/doc/unity-panel-service.1 b/doc/unity-panel-service.1 new file mode 100644 index 000000000..a3bde4289 --- /dev/null +++ b/doc/unity-panel-service.1 @@ -0,0 +1,19 @@ +.TH unity-panel-service "1" "8 December 2010" "" "Linux User's Manual" + +.SH NAME +unity-panel-service \- program for drawing the panel with the unity shell. + +.SH SYNOPSIS +.B unity-panel-service +.br + +.SH DESCRIPTION +The \fBunity-panel-service\fP program is normally started automatically by the Unity shell (which gets started as a compiz module) and is used to draw panels which can then be used for the global menu, or to hold indicators. + +.SH OPTIONS +\fBunity-panel-service\fP takes no options. + +.SH NOTES + +.SH "SEE ALSO" + diff --git a/doc/unity.1 b/doc/unity.1 new file mode 100644 index 000000000..7a6d941f5 --- /dev/null +++ b/doc/unity.1 @@ -0,0 +1,29 @@ +.TH unity "1" "9 December 2010" "" "Linux User's Manual" + +.SH NAME +unity \- wrapper for starting the unity shell and handling fallback + +.SH SYNOPSIS +.B unity +.RI [ options ] +.br + +.SH DESCRIPTION +The \fBunity\fP program can be used to start the Unity shell as a compiz module, and to specify how to handle logging, debugging, as well as how to deal with the user's profile. + +.SH OPTIONS +.IP \fB\-\-advanced\-debug\fP +Runs unity under debugging (using GDB or another debugger tool) to help tracking issues. Should only be used on request from a developper following a bug report. + +.IP \fB\-\-log\fP\ \fIfilename\fP +This parameter, followed by a path or filename, tells the Unity shell to store logs in the specified file. + +.IP \fB\-\-reset\fP +This option allows the user to reset profile parameters in compiz and restart the Unity shell with default settings. + +.IP \fB\-\-verbose\fP +This option turns on displaying additional debugging output for the Unity shell. It can be used by the user to debug configuration issues. This option is often used along with the \fB\-\-log\fP option to save output to a file. + +.SH "SEE ALSO" +.B unity-panel-service +(1) diff --git a/libunity/CMakeLists.txt b/libunity/CMakeLists.txt index d3480f81f..2170ce9fb 100644 --- a/libunity/CMakeLists.txt +++ b/libunity/CMakeLists.txt @@ -7,12 +7,13 @@ set (PREFIX ${CMAKE_INSTALL_PREFIX}) set (DOLLAR "$") # You hear that? It's kittens being killed by the gods of cmake configure_file (${CMAKE_CURRENT_SOURCE_DIR}/unity.pc.cmake ${CMAKE_BINARY_DIR}/libunity/${PKGNAME}.pc) install (FILES ${CMAKE_BINARY_DIR}/libunity/${PKGNAME}.pc DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig/) +install (FILES ${CMAKE_BINARY_DIR}/libunity/${PKGNAME}.vapi DESTINATION ${CMAKE_INSTALL_PREFIX}/share/vala/vapi) # # libunity # find_package(PkgConfig) -pkg_check_modules(DEPS REQUIRED gobject-2.0 gio-2.0 gtk+-2.0 gthread-2.0 dee-1.0 gee-1.0 dbus-glib-1 gconf-2.0) +pkg_check_modules(DEPS REQUIRED gobject-2.0 gio-2.0 gtk+-2.0 gthread-2.0 dee-1.0 gee-1.0 gconf-2.0) # Bump this one when a binary-incompatible change is introduced set (libunity_SOVERSION ${UNITY_MAJOR}) @@ -53,7 +54,7 @@ vala_precompile (VALA_C unity-place-activation.vala unity-io.vala unity-appinfo-manager.vala perf-logger.vala - PACKAGES gtk+-2.0 gio-2.0 glib-2.0 gobject-2.0 gee-1.0 dbus-glib-1 gio-unix-2.0 + PACKAGES gtk+-2.0 gio-2.0 glib-2.0 gobject-2.0 gee-1.0 gio-unix-2.0 OPTIONS --thread CUSTOM_VAPIS ../vapi/dee-1.0.vapi ../vapi/config.vapi GENERATE_VAPI unity diff --git a/libunity/unity-place-activation.vala b/libunity/unity-place-activation.vala index 2b5602e5b..b1efd59ea 100644 --- a/libunity/unity-place-activation.vala +++ b/libunity/unity-place-activation.vala @@ -25,6 +25,9 @@ * both Vala and C. * */ + +using GLib; + namespace Unity.Place { /** @@ -45,7 +48,7 @@ namespace Unity.Place { * You can use the ActivationStatus enumeration to have type safe * return values. */ - public async abstract uint32 activate (string uri) throws DBus.Error; + public async abstract uint32 activate (string uri) throws IOError; } /** diff --git a/libunity/unity-place-browser.vala b/libunity/unity-place-browser.vala index 8fbeed7c7..e83beadcd 100644 --- a/libunity/unity-place-browser.vala +++ b/libunity/unity-place-browser.vala @@ -18,6 +18,7 @@ * */ +using GLib; using Gee; /* @@ -54,17 +55,17 @@ namespace Unity.Place { /** * Returns the new browsing state after the operation has been performed */ - public abstract _BrowsingState[] go_back () throws DBus.Error; + public abstract _BrowsingState[] go_back () throws IOError; /** * Returns the new browsing state after the operation has been performed */ - public abstract _BrowsingState[] go_forward () throws DBus.Error; + public abstract _BrowsingState[] go_forward () throws IOError; /** * Returns the current browsing state */ - public abstract _BrowsingState[] get_state () throws DBus.Error; + public abstract _BrowsingState[] get_state () throws IOError; } /** diff --git a/libunity/unity-place.vala b/libunity/unity-place.vala index ea6ad787b..b4899f4e3 100644 --- a/libunity/unity-place.vala +++ b/libunity/unity-place.vala @@ -36,8 +36,8 @@ * */ +using GLib; using Dee; -using DBus; namespace Unity.Place { @@ -455,7 +455,7 @@ namespace Unity.Place { [DBus (name = "com.canonical.Unity.Place")] private interface Service : GLib.Object { - public abstract _EntryInfo[] get_entries () throws DBus.Error; + public abstract _EntryInfo[] get_entries () throws IOError; public signal void entry_added (_EntryInfo entry); @@ -471,14 +471,14 @@ namespace Unity.Place { private interface EntryService : GLib.Object { public abstract void set_global_search (string search, - HashTable<string,string> hints) throws DBus.Error; + HashTable<string,string> hints) throws IOError; public abstract void set_search (string search, - HashTable<string,string> hints) throws DBus.Error; + HashTable<string,string> hints) throws IOError; - public abstract void set_active (bool is_active) throws DBus.Error; + public abstract void set_active (bool is_active) throws IOError; - public abstract void set_active_section (uint section_id) throws DBus.Error; + public abstract void set_active_section (uint section_id) throws IOError; public signal void entry_renderer_info_changed (_RendererInfo renderer_info); @@ -497,7 +497,8 @@ namespace Unity.Place { { private string _dbus_path; private HashTable<string,EntryServiceImpl> entries; - private bool _exported; + private uint _service_dbus_id = 0; + private uint _activation_dbus_id = 0; /* * Properties @@ -510,7 +511,7 @@ namespace Unity.Place { } public bool exported { - get { return _exported; } + get { return _service_dbus_id != 0; } } public Activation? activation { get; set; default = null; } @@ -557,13 +558,15 @@ namespace Unity.Place { var entry = new EntryServiceImpl(entry_info); entries.insert (entry_info.dbus_path, entry); - if (_exported) + + /* If the place is exported then also export the new entry */ + if (exported) { try { entry.export (); - } catch (DBus.Error e) { - critical ("Failed to export place entry '%s': %s", - entry_info.dbus_path, e.message); + } catch (IOError e) { + critical ("Failed to export entry '%s': %s", + entry.entry_info.dbus_path, e.message); } } entry_added (entry_info.get_raw ()); @@ -614,12 +617,12 @@ namespace Unity.Place { return; entry_removed (dbus_path); - if (_exported) + if (exported) { try { entry.unexport (); - } catch (DBus.Error e) { - critical ("Failed to unexport place entry '%s': %s", + } catch (IOError e) { + critical ("Failed to unexport '%s': %s", entry.entry_info.dbus_path, e.message); } } @@ -627,30 +630,32 @@ namespace Unity.Place { entries.remove (dbus_path); } - public void export () throws DBus.Error + public void export () throws IOError { - var conn = DBus.Bus.get (DBus.BusType. SESSION); - conn.register_object (_dbus_path, this); + var conn = Bus.get_sync(BusType.SESSION); + _service_dbus_id = conn.register_object (_dbus_path, this as Service); + _activation_dbus_id = conn.register_object (_dbus_path, this as Activation); foreach (var entry in entries.get_values ()) { entry.export (); } - _exported = true; notify_property("exported"); } - public void unexport () throws DBus.Error + public void unexport () throws IOError { foreach (var entry in entries.get_values ()) { entry.unexport (); } - var conn = DBus.Bus.get (DBus.BusType. SESSION); - conn.unregister_object (this); + var conn = Bus.get_sync (BusType.SESSION); + conn.unregister_object (_service_dbus_id); + conn.unregister_object (_activation_dbus_id); - _exported = false; + _service_dbus_id = 0; + _activation_dbus_id = 0; notify_property("exported"); } @@ -664,7 +669,7 @@ namespace Unity.Place { try { uint32 activated = yield activation.activate (uri); return activated; - } catch (DBus.Error e) { + } catch (IOError e) { return ActivationStatus.NOT_ACTIVATED; } } @@ -679,7 +684,7 @@ namespace Unity.Place { */ private class EntryServiceImpl : GLib.Object, EntryService { - private bool _exported = false; + private uint _dbus_id = 0; private EntryInfo _entry_info; /* Queue up change signals in order not to flood the bus on rapid changes */ @@ -688,24 +693,25 @@ namespace Unity.Place { /* Keep a ref to the previous browser to properly handle it leaving and * entering the bus */ private Browser? _browser = null; + + /* DBus registration id set if we've registered the browser on the bus */ + private uint _browser_dbus_id = 0; /* * Properties */ - public EntryInfo entry_info { get { return _entry_info; } construct { _entry_info = value; } } public bool exported { - get { return _exported; } + get { return _dbus_id != 0; } } /* * Constructors */ - public EntryServiceImpl (EntryInfo entry_info) { GLib.Object(entry_info : entry_info); @@ -750,46 +756,46 @@ namespace Unity.Place { * Internal API */ - public void export () throws DBus.Error + public void export () throws IOError { - var conn = DBus.Bus.get (DBus.BusType. SESSION); - conn.register_object (_entry_info.dbus_path, this); + var conn = Bus.get_sync (BusType.SESSION); + _dbus_id = conn.register_object (_entry_info.dbus_path, this as EntryService); - if (_entry_info.browser != null) + if (_entry_info.browser != null && _browser_dbus_id == 0) { debug ("Exporting browser at '%s'", _entry_info.browser.dbus_path); - conn.register_object (_entry_info.browser.dbus_path, - _entry_info.browser.get_service ()); + _browser_dbus_id = conn.register_object (_entry_info.browser.dbus_path, + _entry_info.browser.get_service ()); } else debug ("No browser to export"); - _exported = true; notify_property("exported"); } - public void unexport () throws DBus.Error + public void unexport () throws IOError { - var conn = DBus.Bus.get (DBus.BusType. SESSION); - conn.unregister_object (this); + var conn = Bus.get_sync (BusType.SESSION); + conn.unregister_object (_dbus_id); - if (_entry_info.browser != null) + if (_entry_info.browser != null && _browser_dbus_id != 0) { debug ("Unexporting browser '%s'", _entry_info.browser.dbus_path); - conn.unregister_object (_entry_info.browser.get_service ()); + conn.unregister_object (_browser_dbus_id); + _browser_dbus_id = 0; } - _exported = false; + _dbus_id = 0; notify_property("exported"); } private void on_browser_changed (GLib.Object obj, ParamSpec pspec) { - DBus.Connection conn; + DBusConnection conn; try { - conn = DBus.Bus.get (DBus.BusType. SESSION); - } catch (DBus.Error e) { + conn = Bus.get_sync (BusType.SESSION); + } catch (IOError e) { warning ("Unable to connect to session bus: %s", e.message); return; } @@ -798,20 +804,27 @@ namespace Unity.Place { if (_browser == entry_info.browser) return; - /* clear previous browser if any */ - if (_browser != null && _exported) + /* Unexport previous browser if relevant */ + if (_browser != null && _browser_dbus_id != 0) { debug ("Unexporting browser '%s'", _browser.dbus_path); - conn.unregister_object (_browser.get_service ()); + conn.unregister_object (_browser_dbus_id); } _browser = entry_info.browser; + _browser_dbus_id = 0; /* Export the new one if any */ - if (_browser != null && _exported) + if (_browser != null) { debug ("Exporting browser '%s'", _browser.dbus_path); - conn.register_object (_browser.dbus_path, _browser.get_service ()); + try { + _browser_dbus_id = conn.register_object (_browser.dbus_path, + _browser.get_service ()); + } catch (IOError e) { + critical ("failed to export browser '%s': %s", + _browser.dbus_path, e.message); + } } } @@ -1026,7 +1039,7 @@ namespace Unity.Place { return result; } - public void export () throws DBus.Error + public void export () throws IOError { /* Export the Place and Activation insterfaces */ service.export (); @@ -1035,7 +1048,7 @@ namespace Unity.Place { notify_property("exported"); } - public void unexport () throws DBus.Error + public void unexport () throws IOError { service.unexport (); _exported = false; diff --git a/libunity/unity.pc.cmake b/libunity/unity.pc.cmake index d4164bdc3..f851f1fa0 100644 --- a/libunity/unity.pc.cmake +++ b/libunity/unity.pc.cmake @@ -8,5 +8,5 @@ Description: Library for developing services integrating with the Unity Shell Version: @UNITY_VERSION@ Libs: -L@DOLLAR@{libdir} -lunity Cflags: -I@DOLLAR@{includedir}/${PKGNAME}/unity -Requires: glib-2.0 gthread-2.0 gobject-2.0 gio-2.0 gio-unix-2.0 dbus-glib-1 gtk+-2.0 dee-1.0 gee-1.0 +Requires: glib-2.0 gthread-2.0 gobject-2.0 gio-2.0 gio-unix-2.0 gtk+-2.0 dee-1.0 gee-1.0 diff --git a/po/unity.pot b/po/unity.pot index 8cdb2e483..3950036e4 100644 --- a/po/unity.pot +++ b/po/unity.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: ayatana-dev@lists.launchpad.net\n" -"POT-Creation-Date: 2010-12-15 16:03+0000\n" +"POT-Creation-Date: 2011-01-11 12:40-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/resources/2indicate_54x54.png b/resources/2indicate_54x54.png Binary files differdeleted file mode 100644 index 5b89cbc3c..000000000 --- a/resources/2indicate_54x54.png +++ /dev/null diff --git a/resources/3indicate_54x54.png b/resources/3indicate_54x54.png Binary files differdeleted file mode 100644 index 1bfb72bc8..000000000 --- a/resources/3indicate_54x54.png +++ /dev/null diff --git a/resources/4indicate_54x54.png b/resources/4indicate_54x54.png Binary files differdeleted file mode 100644 index 065677772..000000000 --- a/resources/4indicate_54x54.png +++ /dev/null diff --git a/resources/focused_indicator.png b/resources/focused_indicator.png Binary files differdeleted file mode 100644 index cf70e5aa2..000000000 --- a/resources/focused_indicator.png +++ /dev/null diff --git a/resources/launcher_arrow_ltr.png b/resources/launcher_arrow_ltr.png Binary files differnew file mode 100644 index 000000000..8eca12e02 --- /dev/null +++ b/resources/launcher_arrow_ltr.png diff --git a/resources/launcher_arrow_outline_ltr.png b/resources/launcher_arrow_outline_ltr.png Binary files differnew file mode 100644 index 000000000..d6633f56f --- /dev/null +++ b/resources/launcher_arrow_outline_ltr.png diff --git a/resources/launcher_arrow_outline_rtl.png b/resources/launcher_arrow_outline_rtl.png Binary files differnew file mode 100644 index 000000000..1fdeab89c --- /dev/null +++ b/resources/launcher_arrow_outline_rtl.png diff --git a/resources/launcher_arrow_rtl.png b/resources/launcher_arrow_rtl.png Binary files differnew file mode 100644 index 000000000..6caa92229 --- /dev/null +++ b/resources/launcher_arrow_rtl.png diff --git a/resources/launcher_pip_ltr.png b/resources/launcher_pip_ltr.png Binary files differnew file mode 100644 index 000000000..83700a026 --- /dev/null +++ b/resources/launcher_pip_ltr.png diff --git a/resources/launcher_pip_rtl.png b/resources/launcher_pip_rtl.png Binary files differnew file mode 100644 index 000000000..4665a3cdc --- /dev/null +++ b/resources/launcher_pip_rtl.png diff --git a/resources/round_corner_50x50.png b/resources/round_corner_50x50.png Binary files differdeleted file mode 100644 index 8c29e3a07..000000000 --- a/resources/round_corner_50x50.png +++ /dev/null diff --git a/resources/round_corner_54x54.png b/resources/round_corner_54x54.png Binary files differindex b8eb9597f..f9c152506 100644 --- a/resources/round_corner_54x54.png +++ b/resources/round_corner_54x54.png diff --git a/resources/round_glow_62x62.png b/resources/round_glow_62x62.png Binary files differindex 1cfb902f3..08481dde0 100644 --- a/resources/round_glow_62x62.png +++ b/resources/round_glow_62x62.png diff --git a/resources/round_outline_50x50.png b/resources/round_outline_50x50.png Binary files differdeleted file mode 100644 index db1dd8010..000000000 --- a/resources/round_outline_50x50.png +++ /dev/null diff --git a/resources/round_outline_54x54.png b/resources/round_outline_54x54.png Binary files differindex b6bb3b61c..93e82838c 100644 --- a/resources/round_outline_54x54.png +++ b/resources/round_outline_54x54.png diff --git a/resources/round_shine_54x54.png b/resources/round_shine_54x54.png Binary files differindex 87697f412..cfb1cd86e 100644 --- a/resources/round_shine_54x54.png +++ b/resources/round_shine_54x54.png diff --git a/resources/running_indicator.png b/resources/running_indicator.png Binary files differdeleted file mode 100644 index ab6aab485..000000000 --- a/resources/running_indicator.png +++ /dev/null diff --git a/services/panel-main.c b/services/panel-main.c index 38008587f..8ecf9387d 100644 --- a/services/panel-main.c +++ b/services/panel-main.c @@ -60,6 +60,11 @@ static const gchar introspection_xml[] = " <arg type='i' name='button' direction='in'/>" " </method>" "" + " <method name='ScrollEntry'>" + " <arg type='s' name='entry_id' direction='in'/>" + " <arg type='i' name='delta' direction='in'/>" + " </method>" + "" " <signal name='EntryActivated'>" " <arg type='s' name='entry_id' />" " </signal>" @@ -146,6 +151,15 @@ handle_method_call (GDBusConnection *connection, g_dbus_method_invocation_return_value (invocation, NULL); g_free (entry_id); } + else if (g_strcmp0 (method_name, "ScrollEntry") == 0) + { + gchar *entry_id; + gint32 delta; + g_variant_get (parameters, "(si)", &entry_id, &delta, NULL); + panel_service_scroll_entry (service, entry_id, delta); + g_dbus_method_invocation_return_value (invocation, NULL); + g_free(entry_id); + } } static void @@ -284,6 +298,8 @@ main (gint argc, gchar **argv) PanelService *service; guint owner_id; + g_unsetenv("UBUNTU_MENUPROXY"); + gtk_init (&argc, &argv); gtk_icon_theme_append_search_path (gtk_icon_theme_get_default(), INDICATORICONDIR); diff --git a/services/panel-service.c b/services/panel-service.c index d8527cce3..6b23d7331 100644 --- a/services/panel-service.c +++ b/services/panel-service.c @@ -22,6 +22,7 @@ #include "panel-service.h" +#include <stdlib.h> #include <libindicator/indicator.h> #include <libindicator/indicator-object.h> #include <gtk/gtk.h> @@ -996,6 +997,18 @@ panel_service_show_entry (PanelService *self, } void +panel_service_scroll_entry (PanelService *self, + const gchar *entry_id, + gint32 delta) +{ + PanelServicePrivate *priv = self->priv; + IndicatorObjectEntry *entry = g_hash_table_lookup (priv->id2entry_hash, entry_id); + IndicatorObject *object = g_hash_table_lookup (priv->entry2indicator_hash, entry); + GdkScrollDirection direction = delta > 0 ? GDK_SCROLL_DOWN : GDK_SCROLL_UP; + g_signal_emit_by_name(object, "scroll", abs(delta/120), direction); +} + +void panel_service_get_last_xy (PanelService *self, gint *x, gint *y) diff --git a/services/panel-service.h b/services/panel-service.h index aaca21458..9429482ba 100644 --- a/services/panel-service.h +++ b/services/panel-service.h @@ -84,6 +84,10 @@ void panel_service_show_entry (PanelService *self, gint32 y, gint32 button); +void panel_service_scroll_entry (PanelService *self, + const gchar *entry_id, + gint32 delta); + void panel_service_get_last_xy (PanelService *self, gint *x, gint *y); diff --git a/src/BamfLauncherIcon.cpp b/src/BamfLauncherIcon.cpp index 334963d3d..ad037d588 100644 --- a/src/BamfLauncherIcon.cpp +++ b/src/BamfLauncherIcon.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -59,15 +60,15 @@ BamfLauncherIcon::BamfLauncherIcon (Launcher* IconManager, BamfApplication *app, SetTooltipText (bamf_view_get_name (BAMF_VIEW (app))); SetIconName (icon_name); - SetIconType (LAUNCHER_ICON_TYPE_APPLICATION); + SetIconType (TYPE_APPLICATION); if (bamf_view_is_sticky (BAMF_VIEW (m_App))) - SetQuirk (LAUNCHER_ICON_QUIRK_VISIBLE, true); + SetQuirk (QUIRK_VISIBLE, true); else - SetQuirk (LAUNCHER_ICON_QUIRK_VISIBLE, bamf_view_user_visible (BAMF_VIEW (m_App))); + SetQuirk (QUIRK_VISIBLE, bamf_view_user_visible (BAMF_VIEW (m_App))); - SetQuirk (LAUNCHER_ICON_QUIRK_ACTIVE, bamf_view_is_active (BAMF_VIEW (m_App))); - SetQuirk (LAUNCHER_ICON_QUIRK_RUNNING, bamf_view_is_running (BAMF_VIEW (m_App))); + SetQuirk (QUIRK_ACTIVE, bamf_view_is_active (BAMF_VIEW (m_App))); + SetQuirk (QUIRK_RUNNING, bamf_view_is_running (BAMF_VIEW (m_App))); g_free (icon_name); @@ -104,13 +105,13 @@ BamfLauncherIcon::~BamfLauncherIcon() } void -BamfLauncherIcon::OnWindowMinimized (CompWindow *window) +BamfLauncherIcon::OnWindowMinimized (guint32 xid) { - if (!OwnsWindow (window->id ())) + if (!OwnsWindow (xid)) return; Present (0.5f, 600); - UpdateQuirkTimeDelayed (300, LAUNCHER_ICON_QUIRK_SHIMMER); + UpdateQuirkTimeDelayed (300, QUIRK_SHIMMER); } bool @@ -197,7 +198,7 @@ BamfLauncherIcon::OpenInstance () g_error_free (error); } - UpdateQuirkTime (LAUNCHER_ICON_QUIRK_STARTING); + UpdateQuirkTime (QUIRK_STARTING); } void @@ -306,7 +307,7 @@ BamfLauncherIcon::Focus () g_list_free (children); } -void +bool BamfLauncherIcon::Spread () { BamfView *view; @@ -329,40 +330,69 @@ BamfLauncherIcon::Spread () if (windowList.size () > 1) { std::string *match = PluginAdapter::Default ()->MatchStringForXids (&windowList); + _launcher->SetLastSpreadIcon ((LauncherIcon *) this); PluginAdapter::Default ()->InitiateScale (match); delete match; + g_list_free (children); + return true; } g_list_free (children); + + return false; } void BamfLauncherIcon::OnMouseClick (int button) { - bool scaleWasActive = PluginAdapter::Default ()->IsScaleActive(); - - SimpleLauncherIcon::OnMouseClick (button); + bool scaleWasActive = PluginAdapter::Default ()->IsScaleActive (); + bool onlyOwnWasActive = PluginAdapter::Default ()->IsScaleActive (true); if (button != 1) return; + if (!scaleWasActive || (scaleWasActive && !onlyOwnWasActive)) + _launcher->SetLastSpreadIcon (NULL); + bool active, running; active = bamf_view_is_active (BAMF_VIEW (m_App)); running = bamf_view_is_running (BAMF_VIEW (m_App)); + /* Behaviour: + * Nothing running -> launch application + * Running and active -> spread application + * Spread is active and different icon pressed -> change spread + * Spread is active -> Spread de-activated, and fall through + */ + if (!running) { - if (GetQuirk (LAUNCHER_ICON_QUIRK_STARTING)) + if (GetQuirk (QUIRK_STARTING)) return; - SetQuirk (LAUNCHER_ICON_QUIRK_STARTING, true); + SetQuirk (QUIRK_STARTING, true); OpenInstance (); return; } + else if (scaleWasActive) + { + if (_launcher->GetLastSpreadIcon () != this) + { + if (!Spread ()) + { + PluginAdapter::Default ()->TerminateScale (); + Focus (); + _launcher->SetLastSpreadIcon (NULL); + } + } + else + SimpleLauncherIcon::OnMouseClick (button); + } else if (!active) Focus (); - else if (!scaleWasActive) + else if (active && !scaleWasActive) Spread (); + } void @@ -380,14 +410,14 @@ BamfLauncherIcon::OnUserVisibleChanged (BamfView *view, gboolean visible, gpoint BamfLauncherIcon *self = (BamfLauncherIcon *) data; if (!bamf_view_is_sticky (BAMF_VIEW (self->m_App))) - self->SetQuirk (LAUNCHER_ICON_QUIRK_VISIBLE, visible); + self->SetQuirk (QUIRK_VISIBLE, visible); } void BamfLauncherIcon::OnRunningChanged (BamfView *view, gboolean running, gpointer data) { BamfLauncherIcon *self = (BamfLauncherIcon *) data; - self->SetQuirk (LAUNCHER_ICON_QUIRK_RUNNING, running); + self->SetQuirk (QUIRK_RUNNING, running); if (running) { @@ -400,14 +430,14 @@ void BamfLauncherIcon::OnActiveChanged (BamfView *view, gboolean active, gpointer data) { BamfLauncherIcon *self = (BamfLauncherIcon *) data; - self->SetQuirk (LAUNCHER_ICON_QUIRK_ACTIVE, active); + self->SetQuirk (QUIRK_ACTIVE, active); } void BamfLauncherIcon::OnUrgentChanged (BamfView *view, gboolean urgent, gpointer data) { BamfLauncherIcon *self = (BamfLauncherIcon *) data; - self->SetQuirk (LAUNCHER_ICON_QUIRK_URGENT, urgent); + self->SetQuirk (QUIRK_URGENT, urgent); } void @@ -416,14 +446,25 @@ BamfLauncherIcon::EnsureWindowState () GList *children, *l; int count = 0; + bool has_visible = false; + children = bamf_view_get_children (BAMF_VIEW (m_App)); for (l = children; l; l = l->next) { - if (BAMF_IS_WINDOW (l->data)) - count++; + if (!BAMF_IS_WINDOW (l->data)) + continue; + + count++; + + guint32 xid = bamf_window_get_xid (BAMF_WINDOW (l->data)); + CompWindow *window = m_Screen->findWindow ((Window) xid); + + if (window && window->defaultViewport () == m_Screen->vp ()) + has_visible = true; } SetRelatedWindows (count); + SetHasVisibleWindow (has_visible); g_list_free (children); } @@ -606,6 +647,7 @@ BamfLauncherIcon::EnsureMenuItemsReady () dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, "Open New Window"); dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); + dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); g_signal_connect (menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, (GCallback) &BamfLauncherIcon::OnLaunch, this); @@ -621,6 +663,7 @@ BamfLauncherIcon::EnsureMenuItemsReady () dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, DBUSMENU_MENUITEM_TOGGLE_CHECK); dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, "Keep In Launcher"); dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); + dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); g_signal_connect (menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, (GCallback) &BamfLauncherIcon::OnTogglePin, this); @@ -642,6 +685,7 @@ BamfLauncherIcon::EnsureMenuItemsReady () dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, "Quit"); dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); + dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true); g_signal_connect (menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, (GCallback) &BamfLauncherIcon::OnQuit, this); diff --git a/src/BamfLauncherIcon.h b/src/BamfLauncherIcon.h index 488ab4740..976cccc27 100644 --- a/src/BamfLauncherIcon.h +++ b/src/BamfLauncherIcon.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -48,7 +49,6 @@ protected: void UpdateIconGeometries (nux::Point3 center); void OnCenterStabilized (nux::Point3 center); - void AddProperties (GVariantBuilder *builder); private: @@ -64,11 +64,11 @@ private: void OpenInstance (); void Focus (); - void Spread (); + bool Spread (); void EnsureMenuItemsReady (); - void OnWindowMinimized (CompWindow *window); + void OnWindowMinimized (guint32 xid); bool OwnsWindow (Window w); static void OnClosed (BamfView *view, gpointer data); diff --git a/src/IntrospectionDBusInterface.cpp b/src/DebugDBusInterface.cpp index 423529e0f..3abfa01f2 100644 --- a/src/IntrospectionDBusInterface.cpp +++ b/src/DebugDBusInterface.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -16,7 +17,7 @@ * Authored by: Alex Launi <alex.launi@canonical.com> */ -#include "IntrospectionDBusInterface.h" +#include "DebugDBusInterface.h" #define UNITY_STATE_DEBUG_BUS_NAME "com.canonical.Unity" @@ -35,8 +36,8 @@ static const GDBusInterfaceVTable si_vtable = static const GDBusArgInfo si_getstate_in_args = { -1, - "piece", - "s", + (gchar *) "piece", + (gchar *) "s", NULL }; static const GDBusArgInfo *const si_getstate_in_arg_pointers[] = { &si_getstate_in_args, NULL }; @@ -45,8 +46,8 @@ static const GDBusArgInfo *const si_getstate_in_arg_pointers[] = { &si_getstate_ static const GDBusArgInfo si_getstate_out_args = { -1, - "state", - "a{sv}", + (gchar *) "state", + (gchar *) "a{sv}", NULL }; static const GDBusArgInfo *const si_getstate_out_arg_pointers[] = { &si_getstate_out_args, NULL }; @@ -54,7 +55,7 @@ static const GDBusArgInfo *const si_getstate_out_arg_pointers[] = { &si_getstate static const GDBusMethodInfo si_method_info_getstate = { -1, - "GetState", + (gchar *) "GetState", (GDBusArgInfo **) &si_getstate_in_arg_pointers, (GDBusArgInfo **) &si_getstate_out_arg_pointers, NULL @@ -65,7 +66,7 @@ static const GDBusMethodInfo *const si_method_info_pointers[] = { &si_method_inf static const GDBusInterfaceInfo si_iface_info = { -1, - "com.canonical.Unity.Debug.Introspection", + (gchar *) "com.canonical.Unity.Debug.Introspection", (GDBusMethodInfo **) &si_method_info_pointers, NULL, NULL, @@ -74,30 +75,30 @@ static const GDBusInterfaceInfo si_iface_info = static Introspectable *_introspectable; -IntrospectionDBusInterface::IntrospectionDBusInterface (Introspectable *introspectable) +DebugDBusInterface::DebugDBusInterface (Introspectable *introspectable) { _introspectable = introspectable; _owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, UNITY_STATE_DEBUG_BUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, - &IntrospectionDBusInterface::OnBusAcquired, - &IntrospectionDBusInterface::OnNameAcquired, - &IntrospectionDBusInterface::OnNameLost, + &DebugDBusInterface::OnBusAcquired, + &DebugDBusInterface::OnNameAcquired, + &DebugDBusInterface::OnNameLost, this, NULL); } -IntrospectionDBusInterface::~IntrospectionDBusInterface () +DebugDBusInterface::~DebugDBusInterface () { g_bus_unown_name (_owner_id); } void -IntrospectionDBusInterface::OnBusAcquired (GDBusConnection *connection, const gchar *name, gpointer data) +DebugDBusInterface::OnBusAcquired (GDBusConnection *connection, const gchar *name, gpointer data) { GError *error = NULL; g_dbus_connection_register_object (connection, - "/com/canonical/Unity/Debug/Introspection", + "/com/canonical/Unity/Debug", (GDBusInterfaceInfo *) &si_iface_info, &si_vtable, NULL, @@ -111,12 +112,12 @@ IntrospectionDBusInterface::OnBusAcquired (GDBusConnection *connection, const gc } void -IntrospectionDBusInterface::OnNameAcquired (GDBusConnection *connection, const gchar *name, gpointer data) +DebugDBusInterface::OnNameAcquired (GDBusConnection *connection, const gchar *name, gpointer data) { } void -IntrospectionDBusInterface::OnNameLost (GDBusConnection *connection, const gchar *name, gpointer data) +DebugDBusInterface::OnNameLost (GDBusConnection *connection, const gchar *name, gpointer data) { } @@ -155,7 +156,7 @@ GetState (const gchar *piece) /* a very contrived example purely for giving QA something purposes */ GVariant* -IntrospectionDBusInterface::BuildFakeReturn () +DebugDBusInterface::BuildFakeReturn () { GVariantBuilder *builder; GVariant *result, *panel_result, *indicators_result, *appmenu_result, *entries_result, *zero_result, *one_result; diff --git a/src/IntrospectionDBusInterface.h b/src/DebugDBusInterface.h index 0a149876a..a56c75816 100644 --- a/src/IntrospectionDBusInterface.h +++ b/src/DebugDBusInterface.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -16,23 +17,18 @@ * Authored by: Alex Launi <alex.launi@canonical.com> */ -#ifndef _STATE_INTROSPECTION_DBUS_INTERFACE_H -#define _STATE_INTROSPECTION_DBUS_INTERFACE_H 1 +#ifndef _DEBUG_DBUS_INTERFACE_H +#define _DEBUG_DBUS_INTERFACE_H 1 #include <glib.h> #include <gio/gio.h> #include "Introspectable.h" -class IntrospectionDBusInterface +class DebugDBusInterface { public: - IntrospectionDBusInterface (Introspectable *introspectable); - ~IntrospectionDBusInterface (); - - /*static void DBusMethodCall (GDBusConnection *connection, const gchar *sender, - const gchar *objectPath, const gchar *ifaceName, - const gchar *methodName, GVariant *parameters, - GDBusMethodInvocation *invocation, gpointer data); */ + DebugDBusInterface (Introspectable *introspectable); + ~DebugDBusInterface (); private: /* methods */ @@ -51,4 +47,4 @@ private: guint _owner_id; }; -#endif +#endif /* _DEBUG_DBUS_INTERFACE_H */ diff --git a/src/FavoriteStore.cpp b/src/FavoriteStore.cpp index 48568c686..295e769bb 100644 --- a/src/FavoriteStore.cpp +++ b/src/FavoriteStore.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/FavoriteStore.h b/src/FavoriteStore.h index de8b13659..246ca5d1a 100644 --- a/src/FavoriteStore.h +++ b/src/FavoriteStore.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/FavoriteStoreGSettings.cpp b/src/FavoriteStoreGSettings.cpp index 6ba2c32d0..73d0ff393 100644 --- a/src/FavoriteStoreGSettings.cpp +++ b/src/FavoriteStoreGSettings.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -24,7 +25,7 @@ #define SETTINGS_NAME "com.canonical.Unity.Launcher" -#define LATEST_SETTINGS_MIGRATION "3.2.0" +#define LATEST_SETTINGS_MIGRATION "3.2.10" static void on_settings_updated (GSettings *settings, const gchar *key, FavoriteStoreGSettings *self); diff --git a/src/FavoriteStoreGSettings.h b/src/FavoriteStoreGSettings.h index f88fd0b1e..a59832910 100644 --- a/src/FavoriteStoreGSettings.h +++ b/src/FavoriteStoreGSettings.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/IndicatorObjectEntryProxy.h b/src/IndicatorObjectEntryProxy.h index 5ec831506..dcf703989 100644 --- a/src/IndicatorObjectEntryProxy.h +++ b/src/IndicatorObjectEntryProxy.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -34,6 +35,7 @@ public: virtual void SetActive (bool active) = 0; virtual bool GetActive () = 0; virtual void ShowMenu (int x, int y, guint32 timestamp, guint32 button) = 0; + virtual void Scroll (int delta) = 0; // Signals sigc::signal<void> updated; diff --git a/src/IndicatorObjectEntryProxyRemote.cpp b/src/IndicatorObjectEntryProxyRemote.cpp index 56c30a261..8318909aa 100644 --- a/src/IndicatorObjectEntryProxyRemote.cpp +++ b/src/IndicatorObjectEntryProxyRemote.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -156,3 +157,9 @@ IndicatorObjectEntryProxyRemote::ShowMenu (int x, int y, guint32 timestamp, guin { OnShowMenuRequest.emit (_id, x, y, timestamp, button); } + +void +IndicatorObjectEntryProxyRemote::Scroll (int delta) +{ + OnScroll.emit(_id, delta); +} \ No newline at end of file diff --git a/src/IndicatorObjectEntryProxyRemote.h b/src/IndicatorObjectEntryProxyRemote.h index 3918b24f6..18db4a175 100644 --- a/src/IndicatorObjectEntryProxyRemote.h +++ b/src/IndicatorObjectEntryProxyRemote.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -46,6 +47,7 @@ public: virtual bool GetActive (); virtual void ShowMenu (int x, int y, guint32 timestamp, guint32 button); + virtual void Scroll (int delta); void Refresh (const char *__id, const char *__label, @@ -58,6 +60,7 @@ public: // Signals sigc::signal<void, const char *, int, int, guint32, guint32> OnShowMenuRequest; + sigc::signal<void, const char *, int> OnScroll; public: bool _dirty; diff --git a/src/IndicatorObjectFactory.h b/src/IndicatorObjectFactory.h index a6f2755ef..c19be3cff 100644 --- a/src/IndicatorObjectFactory.h +++ b/src/IndicatorObjectFactory.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/IndicatorObjectFactoryRemote.cpp b/src/IndicatorObjectFactoryRemote.cpp index 4257fabcd..870c592ee 100644 --- a/src/IndicatorObjectFactoryRemote.cpp +++ b/src/IndicatorObjectFactoryRemote.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -223,6 +224,22 @@ IndicatorObjectFactoryRemote::OnShowMenuRequestReceived (const char *entry_id, // -------------------------------------------------------------------------- } +void +IndicatorObjectFactoryRemote::OnScrollReceived (const char *entry_id, + int delta) +{ + g_dbus_proxy_call (_proxy, + "ScrollEntry", + g_variant_new ("(si)", + entry_id, + delta), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, + NULL); +} + // We need to unset the last active entry and set the new one as active void IndicatorObjectFactoryRemote::OnEntryActivated (const char *entry_id) @@ -274,6 +291,8 @@ IndicatorObjectFactoryRemote::IndicatorForID (const char *id) remote = new IndicatorObjectProxyRemote (id); remote->OnShowMenuRequest.connect (sigc::mem_fun (this, &IndicatorObjectFactoryRemote::OnShowMenuRequestReceived)); + remote->OnScroll.connect (sigc::mem_fun (this, + &IndicatorObjectFactoryRemote::OnScrollReceived)); _indicators.push_back (remote); @@ -496,8 +515,9 @@ on_proxy_name_owner_changed (GDBusProxy *proxy, if (name_owner == NULL) { - // The panel service has stopped for some reason. Restart it. - remote->Reconnect (); + // The panel service has stopped for some reason. Restart it if not in dev mode + if (! g_getenv ("UNITY_DEV_MODE")) + remote->Reconnect (); } g_free (name_owner); diff --git a/src/IndicatorObjectFactoryRemote.h b/src/IndicatorObjectFactoryRemote.h index 5f9b00611..f1331b3ea 100644 --- a/src/IndicatorObjectFactoryRemote.h +++ b/src/IndicatorObjectFactoryRemote.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -41,6 +42,7 @@ public: void OnRemoteProxyReady (GDBusProxy *proxy); void OnEntryActivated (const char *entry_id); void OnShowMenuRequestReceived (const char *id, int x, int y, guint timestamp, guint32 button); + void OnScrollReceived (const char *id, int delta); void Sync (GVariant *args); void OnEntryActivateRequestReceived (const char *entry_id); void Reconnect (); diff --git a/src/IndicatorObjectProxy.h b/src/IndicatorObjectProxy.h index b6d182130..2c5077d9a 100644 --- a/src/IndicatorObjectProxy.h +++ b/src/IndicatorObjectProxy.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/IndicatorObjectProxyRemote.cpp b/src/IndicatorObjectProxyRemote.cpp index 108cf7124..6ee1ab7df 100644 --- a/src/IndicatorObjectProxyRemote.cpp +++ b/src/IndicatorObjectProxyRemote.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -92,6 +93,8 @@ IndicatorObjectProxyRemote::AddEntry (const gchar *entry_id, remote = new IndicatorObjectEntryProxyRemote (); remote->OnShowMenuRequest.connect (sigc::mem_fun (this, &IndicatorObjectProxyRemote::OnShowMenuRequestReceived)); + remote->OnScroll.connect (sigc::mem_fun(this, + &IndicatorObjectProxyRemote::OnScrollReceived)); _entries.push_back (remote); } @@ -143,3 +146,10 @@ IndicatorObjectProxyRemote::OnShowMenuRequestReceived (const char *entry_id, { OnShowMenuRequest.emit (entry_id, x, y, timestamp, button); } + +void +IndicatorObjectProxyRemote::OnScrollReceived (const char *entry_id, + int delta) +{ + OnScroll.emit(entry_id, delta); +} diff --git a/src/IndicatorObjectProxyRemote.h b/src/IndicatorObjectProxyRemote.h index 8198bf85e..30f7b0a6f 100644 --- a/src/IndicatorObjectProxyRemote.h +++ b/src/IndicatorObjectProxyRemote.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -49,9 +50,11 @@ public: void EndSync (); void OnShowMenuRequestReceived (const char *id, int x, int y, guint timestamp, guint32 button); + void OnScrollReceived (const char *id, int delta); // Signals sigc::signal<void, const char *, int, int, guint32, guint32> OnShowMenuRequest; + sigc::signal<void, const char *, int> OnScroll; private: std::string _name; diff --git a/src/Introspectable.cpp b/src/Introspectable.cpp index a0d39e820..3c52a5c4c 100644 --- a/src/Introspectable.cpp +++ b/src/Introspectable.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/Introspectable.h b/src/Introspectable.h index 5c58b2a7b..b23aa0a07 100644 --- a/src/Introspectable.h +++ b/src/Introspectable.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/Launcher.cpp b/src/Launcher.cpp index 6d8e3fe5a..3a5fabb70 100644 --- a/src/Launcher.cpp +++ b/src/Launcher.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -38,19 +39,19 @@ #include "QuicklistManager.h" #include "QuicklistView.h" -#define ANIM_DURATION_SHORT 125 -#define ANIM_DURATION 200 -#define ANIM_DURATION_LONG 350 - #define URGENT_BLINKS 3 +#define WIGGLE_CYCLES 6 #define MAX_STARTING_BLINKS 5 #define STARTING_BLINK_LAMBDA 3 #define BACKLIGHT_STRENGTH 0.9f +NUX_IMPLEMENT_OBJECT_TYPE (Launcher); + int TimeDelta (struct timespec const *x, struct timespec const *y) + { return ((x->tv_sec - y->tv_sec) * 1000) + ((x->tv_nsec - y->tv_nsec) / 1000000); } @@ -76,29 +77,24 @@ nux::NString gPerspectiveCorrectShader = TEXT ( #version 120 \n\ uniform mat4 ViewProjectionMatrix; \n\ \n\ -attribute vec4 iColor; \n\ attribute vec4 iTexCoord0; \n\ attribute vec4 iVertex; \n\ \n\ varying vec4 varyTexCoord0; \n\ -varying vec4 varyVertexColor; \n\ \n\ void main() \n\ { \n\ varyTexCoord0 = iTexCoord0; \n\ - varyVertexColor = iColor; \n\ gl_Position = ViewProjectionMatrix * iVertex; \n\ } \n\ \n\ [Fragment Shader] \n\ -#version 120 \n\ -#extension GL_ARB_texture_rectangle : enable \n\ +#version 110 \n\ \n\ varying vec4 varyTexCoord0; \n\ -varying vec4 varyVertexColor; \n\ \n\ uniform sampler2D TextureObject0; \n\ -uniform vec4 color0; \n\ +uniform vec4 color0; \n\ vec4 SampleTexture(sampler2D TexObject, vec4 TexCoord) \n\ { \n\ return texture2D(TexObject, TexCoord.st); \n\ @@ -109,9 +105,9 @@ void main() \n\ vec4 tex = varyTexCoord0; \n\ tex.s = tex.s/varyTexCoord0.w; \n\ tex.t = tex.t/varyTexCoord0.w; \n\ - \n\ + \n\ vec4 texel = SampleTexture(TextureObject0, tex); \n\ - gl_FragColor = texel*varyVertexColor; \n\ + gl_FragColor = color0*texel; \n\ } \n\ "); @@ -172,8 +168,6 @@ static void GetInverseScreenPerspectiveMatrix(nux::Matrix4& ViewMatrix, nux::Mat Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , m_ContentOffsetY(0) -, m_RunningIndicator(0) -, m_ActiveIndicator(0) , m_BackgroundLayer(0) , _model (0) { @@ -206,10 +200,11 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE m_ActiveTooltipIcon = NULL; m_ActiveMenuIcon = NULL; + m_LastSpreadIcon = NULL; SetCompositionLayout(m_Layout); - if(!USE_ARB_SHADERS) + if(nux::GetGraphicsEngine ().UsingGLSLCodePath ()) { _shader_program_uv_persp_correction = nux::GetThreadGLDeviceFactory()->CreateShaderProgram(); _shader_program_uv_persp_correction->LoadIShader(gPerspectiveCorrectShader.GetTCharPtr()); @@ -240,8 +235,9 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE _launcher_top_y = 0; _launcher_bottom_y = 0; _folded_z_distance = 10.0f; - _launcher_state = LAUNCHER_FOLDED; _launcher_action_state = ACTION_NONE; + _launch_animation = LAUNCH_ANIMATION_NONE; + _urgent_animation = URGENT_ANIMATION_NONE; _icon_under_mouse = NULL; _icon_mouse_down = NULL; _drag_icon = NULL; @@ -256,6 +252,14 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE _icon_glow_texture = nux::CreateTextureFromFile (PKGDATADIR"/round_glow_62x62.png"); _progress_bar_trough = nux::CreateTextureFromFile (PKGDATADIR"/progress_bar_trough.png"); _progress_bar_fill = nux::CreateTextureFromFile (PKGDATADIR"/progress_bar_fill.png"); + + _pip_ltr = nux::CreateTextureFromFile (PKGDATADIR"/launcher_pip_ltr.png"); + _arrow_ltr = nux::CreateTextureFromFile (PKGDATADIR"/launcher_arrow_ltr.png"); + _arrow_empty_ltr = nux::CreateTextureFromFile (PKGDATADIR"/launcher_arrow_outline_ltr.png"); + + _pip_rtl = nux::CreateTextureFromFile (PKGDATADIR"/launcher_pip_rtl.png"); + _arrow_rtl = nux::CreateTextureFromFile (PKGDATADIR"/launcher_arrow_rtl.png"); + _arrow_empty_rtl = nux::CreateTextureFromFile (PKGDATADIR"/launcher_arrow_outline_rtl.png"); _enter_y = 0; _dnd_security = 15; @@ -269,8 +273,11 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE _hidden = false; _mouse_inside_launcher = false; _mouse_inside_trigger = false; + _force_show_launcher = false; _window_over_launcher = false; _render_drag_window = false; + _backlight_always_on = false; + // 0 out timers to avoid wonky startups _enter_time.tv_sec = 0; @@ -390,35 +397,35 @@ void Launcher::EnsureAnimation () bool Launcher::IconNeedsAnimation (LauncherIcon *icon, struct timespec const ¤t) { - struct timespec time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_VISIBLE); + struct timespec time = icon->GetQuirkTime (LauncherIcon::QUIRK_VISIBLE); if (TimeDelta (¤t, &time) < ANIM_DURATION_SHORT) return true; - time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_RUNNING); + time = icon->GetQuirkTime (LauncherIcon::QUIRK_RUNNING); if (TimeDelta (¤t, &time) < ANIM_DURATION_SHORT) return true; - time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_STARTING); + time = icon->GetQuirkTime (LauncherIcon::QUIRK_STARTING); if (TimeDelta (¤t, &time) < (ANIM_DURATION_LONG * MAX_STARTING_BLINKS * STARTING_BLINK_LAMBDA * 2)) return true; - time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_URGENT); + time = icon->GetQuirkTime (LauncherIcon::QUIRK_URGENT); if (TimeDelta (¤t, &time) < (ANIM_DURATION_LONG * URGENT_BLINKS * 2)) return true; - time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_PRESENTED); + time = icon->GetQuirkTime (LauncherIcon::QUIRK_PRESENTED); if (TimeDelta (¤t, &time) < ANIM_DURATION) return true; - time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_SHIMMER); + time = icon->GetQuirkTime (LauncherIcon::QUIRK_SHIMMER); if (TimeDelta (¤t, &time) < ANIM_DURATION_LONG) return true; - time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_CENTER_SAVED); + time = icon->GetQuirkTime (LauncherIcon::QUIRK_CENTER_SAVED); if (TimeDelta (¤t, &time) < ANIM_DURATION) return true; - time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_PROGRESS); + time = icon->GetQuirkTime (LauncherIcon::QUIRK_PROGRESS); if (TimeDelta (¤t, &time) < ANIM_DURATION) return true; @@ -495,15 +502,15 @@ void Launcher::SetTimeStruct (struct timespec *timer, struct timespec *sister, i float IconVisibleProgress (LauncherIcon *icon, struct timespec const ¤t) { - if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_VISIBLE)) + if (icon->GetQuirk (LauncherIcon::QUIRK_VISIBLE)) { - struct timespec icon_visible_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_VISIBLE); + struct timespec icon_visible_time = icon->GetQuirkTime (LauncherIcon::QUIRK_VISIBLE); int enter_ms = TimeDelta (¤t, &icon_visible_time); return CLAMP ((float) enter_ms / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f); } else { - struct timespec icon_hide_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_VISIBLE); + struct timespec icon_hide_time = icon->GetQuirkTime (LauncherIcon::QUIRK_VISIBLE); int hide_ms = TimeDelta (¤t, &icon_hide_time); return 1.0f - CLAMP ((float) hide_ms / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f); } @@ -537,11 +544,11 @@ void Launcher::SetDndDelta (float x, float y, nux::Geometry geo, struct timespec float Launcher::IconPresentProgress (LauncherIcon *icon, struct timespec const ¤t) { - struct timespec icon_present_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_PRESENTED); + struct timespec icon_present_time = icon->GetQuirkTime (LauncherIcon::QUIRK_PRESENTED); int ms = TimeDelta (¤t, &icon_present_time); float result = CLAMP ((float) ms / (float) ANIM_DURATION, 0.0f, 1.0f); - if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_PRESENTED)) + if (icon->GetQuirk (LauncherIcon::QUIRK_PRESENTED)) return result; else return 1.0f - result; @@ -549,11 +556,16 @@ float Launcher::IconPresentProgress (LauncherIcon *icon, struct timespec const & float Launcher::IconUrgentProgress (LauncherIcon *icon, struct timespec const ¤t) { - struct timespec urgent_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_URGENT); + struct timespec urgent_time = icon->GetQuirkTime (LauncherIcon::QUIRK_URGENT); int urgent_ms = TimeDelta (¤t, &urgent_time); - float result = CLAMP ((float) urgent_ms / (float) (ANIM_DURATION_LONG * URGENT_BLINKS * 2), 0.0f, 1.0f); + float result; + + if (_urgent_animation == URGENT_ANIMATION_WIGGLE) + result = CLAMP ((float) urgent_ms / (float) (ANIM_DURATION_SHORT * WIGGLE_CYCLES), 0.0f, 1.0f); + else + result = CLAMP ((float) urgent_ms / (float) (ANIM_DURATION_LONG * URGENT_BLINKS * 2), 0.0f, 1.0f); - if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_URGENT)) + if (icon->GetQuirk (LauncherIcon::QUIRK_URGENT)) return result; else return 1.0f - result; @@ -561,83 +573,117 @@ float Launcher::IconUrgentProgress (LauncherIcon *icon, struct timespec const &c float Launcher::IconShimmerProgress (LauncherIcon *icon, struct timespec const ¤t) { - struct timespec shimmer_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_SHIMMER); + struct timespec shimmer_time = icon->GetQuirkTime (LauncherIcon::QUIRK_SHIMMER); int shimmer_ms = TimeDelta (¤t, &shimmer_time); return CLAMP ((float) shimmer_ms / (float) ANIM_DURATION_LONG, 0.0f, 1.0f); } float Launcher::IconCenterTransitionProgress (LauncherIcon *icon, struct timespec const ¤t) { - struct timespec save_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_CENTER_SAVED); + struct timespec save_time = icon->GetQuirkTime (LauncherIcon::QUIRK_CENTER_SAVED); int save_ms = TimeDelta (¤t, &save_time); return CLAMP ((float) save_ms / (float) ANIM_DURATION, 0.0f, 1.0f); } float Launcher::IconUrgentPulseValue (LauncherIcon *icon, struct timespec const ¤t) { - if (!icon->GetQuirk (LAUNCHER_ICON_QUIRK_URGENT)) + if (!icon->GetQuirk (LauncherIcon::QUIRK_URGENT)) return 1.0f; // we are full on in a normal condition double urgent_progress = (double) IconUrgentProgress (icon, current); return 0.5f + (float) (std::cos (M_PI * (float) (URGENT_BLINKS * 2) * urgent_progress)) * 0.5f; } +float Launcher::IconUrgentWiggleValue (LauncherIcon *icon, struct timespec const ¤t) +{ + if (!icon->GetQuirk (LauncherIcon::QUIRK_URGENT)) + return 0.0f; // we are full on in a normal condition + + double urgent_progress = (double) IconUrgentProgress (icon, current); + return 0.3f * (float) (std::sin (M_PI * (float) (WIGGLE_CYCLES * 2) * urgent_progress)) * 0.5f; +} + +float Launcher::IconStartingBlinkValue (LauncherIcon *icon, struct timespec const ¤t) +{ + struct timespec starting_time = icon->GetQuirkTime (LauncherIcon::QUIRK_STARTING); + int starting_ms = TimeDelta (¤t, &starting_time); + double starting_progress = (double) CLAMP ((float) starting_ms / (float) (ANIM_DURATION_LONG * STARTING_BLINK_LAMBDA), 0.0f, 1.0f); + return 0.5f + (float) (std::cos (M_PI * (_backlight_always_on ? 4.0f : 3.0f) * starting_progress)) * 0.5f; +} + float Launcher::IconStartingPulseValue (LauncherIcon *icon, struct timespec const ¤t) { - struct timespec starting_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_STARTING); + struct timespec starting_time = icon->GetQuirkTime (LauncherIcon::QUIRK_STARTING); int starting_ms = TimeDelta (¤t, &starting_time); double starting_progress = (double) CLAMP ((float) starting_ms / (float) (ANIM_DURATION_LONG * MAX_STARTING_BLINKS * STARTING_BLINK_LAMBDA * 2), 0.0f, 1.0f); - if (starting_progress == 1.0f && !icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING)) + if (starting_progress == 1.0f && !icon->GetQuirk (LauncherIcon::QUIRK_RUNNING)) { - icon->SetQuirk (LAUNCHER_ICON_QUIRK_STARTING, false); - icon->ResetQuirkTime (LAUNCHER_ICON_QUIRK_STARTING); + icon->SetQuirk (LauncherIcon::QUIRK_STARTING, false); + icon->ResetQuirkTime (LauncherIcon::QUIRK_STARTING); } - return 1.0f - (0.5f + (float) (std::cos (M_PI * (float) (MAX_STARTING_BLINKS * 2) * starting_progress)) * 0.5f); + return 0.5f + (float) (std::cos (M_PI * (float) (MAX_STARTING_BLINKS * 2) * starting_progress)) * 0.5f; } float Launcher::IconBackgroundIntensity (LauncherIcon *icon, struct timespec const ¤t) { float result = 0.0f; - struct timespec running_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_RUNNING); + + struct timespec running_time = icon->GetQuirkTime (LauncherIcon::QUIRK_RUNNING); int running_ms = TimeDelta (¤t, &running_time); float running_progress = CLAMP ((float) running_ms / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f); + + if (!icon->GetQuirk (LauncherIcon::QUIRK_RUNNING)) + running_progress = 1.0f - running_progress; // After we finish a fade in from running, we can reset the quirk - if (running_progress == 1.0f && icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING)) - { - icon->SetQuirk (LAUNCHER_ICON_QUIRK_STARTING, false); - icon->ResetQuirkTime (LAUNCHER_ICON_QUIRK_STARTING); - } - - result = IconStartingPulseValue (icon, current) * BACKLIGHT_STRENGTH; - - if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING)) - { - // running progress fades in whatever the pulsing did not fill in already - result += running_progress * (BACKLIGHT_STRENGTH - result); - - // urgent serves to bring the total down only - if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_URGENT)) - result *= 0.2f + 0.8f * IconUrgentPulseValue (icon, current); - } + if (running_progress == 1.0f && icon->GetQuirk (LauncherIcon::QUIRK_RUNNING)) + icon->SetQuirk (LauncherIcon::QUIRK_STARTING, false); + + float backlight_strength; + if (_backlight_always_on) + backlight_strength = BACKLIGHT_STRENGTH; else + backlight_strength = BACKLIGHT_STRENGTH * running_progress; + + switch (_launch_animation) { - // modestly evil - result += BACKLIGHT_STRENGTH - running_progress * BACKLIGHT_STRENGTH; + case LAUNCH_ANIMATION_NONE: + result = backlight_strength; + break; + case LAUNCH_ANIMATION_BLINK: + if (_backlight_always_on) + result = IconStartingBlinkValue (icon, current); + else + result = backlight_strength; // The blink concept is a failure in this case (it just doesn't work right) + break; + case LAUNCH_ANIMATION_PULSE: + if (running_progress == 1.0f && icon->GetQuirk (LauncherIcon::QUIRK_RUNNING)) + icon->ResetQuirkTime (LauncherIcon::QUIRK_STARTING); + + result = backlight_strength; + if (_backlight_always_on) + result *= CLAMP (running_progress + IconStartingPulseValue (icon, current), 0.0f, 1.0f); + else + result += (BACKLIGHT_STRENGTH - result) * (1.0f - IconStartingPulseValue (icon, current)); + break; } - + + // urgent serves to bring the total down only + if (icon->GetQuirk (LauncherIcon::QUIRK_URGENT) && _urgent_animation == URGENT_ANIMATION_PULSE) + result *= 0.2f + 0.8f * IconUrgentPulseValue (icon, current); + return result; } float Launcher::IconProgressBias (LauncherIcon *icon, struct timespec const ¤t) { - struct timespec icon_progress_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_PROGRESS); + struct timespec icon_progress_time = icon->GetQuirkTime (LauncherIcon::QUIRK_PROGRESS); int ms = TimeDelta (¤t, &icon_progress_time); float result = CLAMP ((float) ms / (float) ANIM_DURATION, 0.0f, 1.0f); - if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_PROGRESS)) + if (icon->GetQuirk (LauncherIcon::QUIRK_PROGRESS)) return -1.0f + result; else return result; @@ -645,36 +691,42 @@ float Launcher::IconProgressBias (LauncherIcon *icon, struct timespec const &cur void Launcher::SetupRenderArg (LauncherIcon *icon, struct timespec const ¤t, RenderArg &arg) { - arg.icon = icon; - arg.alpha = 1.0f; - arg.running_arrow = icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING); - arg.active_arrow = icon->GetQuirk (LAUNCHER_ICON_QUIRK_ACTIVE); - arg.running_colored = icon->GetQuirk (LAUNCHER_ICON_QUIRK_URGENT); - arg.active_colored = false; - arg.x_rotation = 0.0f; - arg.y_rotation = 0.0f; - arg.z_rotation = 0.0f; - arg.skip = false; - arg.stick_thingy = false; - arg.progress_bias = IconProgressBias (icon, current); - arg.progress = CLAMP (icon->GetProgress (), 0.0f, 1.0f); + arg.icon = icon; + arg.alpha = 1.0f; + arg.running_arrow = icon->GetQuirk (LauncherIcon::QUIRK_RUNNING); + arg.active_arrow = icon->GetQuirk (LauncherIcon::QUIRK_ACTIVE); + arg.running_colored = icon->GetQuirk (LauncherIcon::QUIRK_URGENT); + arg.running_on_viewport = icon->HasVisibleWindow (); + arg.active_colored = false; + arg.x_rotation = 0.0f; + arg.y_rotation = 0.0f; + arg.z_rotation = 0.0f; + arg.skip = false; + arg.stick_thingy = false; + arg.progress_bias = IconProgressBias (icon, current); + arg.progress = CLAMP (icon->GetProgress (), 0.0f, 1.0f); // we dont need to show strays - if (!icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING)) + if (!icon->GetQuirk (LauncherIcon::QUIRK_RUNNING)) arg.window_indicators = 0; else - arg.window_indicators = MIN (4, icon->RelatedWindows ()); + arg.window_indicators = icon->RelatedWindows (); arg.backlight_intensity = IconBackgroundIntensity (icon, current); arg.shimmer_progress = IconShimmerProgress (icon, current); float urgent_progress = IconUrgentProgress (icon, current); - if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_URGENT)) + if (icon->GetQuirk (LauncherIcon::QUIRK_URGENT)) urgent_progress = CLAMP (urgent_progress * 3.0f, 0.0f, 1.0f); // we want to go 3x faster than the urgent normal cycle else urgent_progress = CLAMP (urgent_progress * 3.0f - 2.0f, 0.0f, 1.0f); // we want to go 3x faster than the urgent normal cycle arg.glow_intensity = urgent_progress; + + if (icon->GetQuirk (LauncherIcon::QUIRK_URGENT) && _urgent_animation == URGENT_ANIMATION_WIGGLE) + { + arg.z_rotation = IconUrgentWiggleValue (icon, current); + } } void Launcher::FillRenderArg (LauncherIcon *icon, @@ -696,7 +748,7 @@ void Launcher::FillRenderArg (LauncherIcon *icon, float size_modifier = IconVisibleProgress (icon, current); if (size_modifier < 1.0f) { - arg.alpha = size_modifier; + arg.alpha *= size_modifier; center.z = 300.0f * (1.0f - size_modifier); } @@ -901,6 +953,18 @@ void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args, /* End Render Layout Logic */ +void Launcher::ForceShowLauncherStart () +{ + _force_show_launcher = true; + EnsureHiddenState (); +} + +void Launcher::ForceShowLauncherEnd () +{ + _force_show_launcher = false; + SetupAutohideTimer (); +} + void Launcher::SetHidden (bool hidden) { if (hidden == _hidden) @@ -928,6 +992,7 @@ Launcher::EnsureHiddenState () { if (!_mouse_inside_trigger && !_mouse_inside_launcher && + !_force_show_launcher && _launcher_action_state == ACTION_NONE && !QuicklistManager::Default ()->Current() && _window_over_launcher) @@ -946,8 +1011,10 @@ Launcher::CheckWindowOverLauncher () for (it = window_list.begin (); it != window_list.end (); it++) { CompWindow *window = *it; + int intersect_types = CompWindowTypeNormalMask | CompWindowTypeDialogMask | + CompWindowTypeModalDialogMask; - if (window->type () != CompWindowTypeNormalMask || !window->isMapped () || !window->isViewable ()) + if (!(window->type () & intersect_types) || !window->isMapped () || !window->isViewable ()) continue; if (CompRegion (window->inputRect ()).intersects (CompRect (geo.x, geo.y, geo.width, geo.height))) @@ -963,7 +1030,7 @@ Launcher::CheckWindowOverLauncher () } void -Launcher::OnWindowMaybeIntellihide (CompWindow *window) +Launcher::OnWindowMaybeIntellihide (guint32 xid) { if (_autohide) CheckWindowOverLauncher (); @@ -1037,6 +1104,50 @@ void Launcher::SetFloating (bool floating) EnsureAnimation (); } +void Launcher::SetBacklightAlwaysOn (bool always_on) +{ + if (_backlight_always_on == always_on) + return; + + _backlight_always_on = always_on; + EnsureAnimation (); +} + +bool Launcher::GetBacklightAlwaysOn () +{ + return _backlight_always_on; +} + +void +Launcher::SetLaunchAnimation (LaunchAnimation animation) +{ + if (_launch_animation == animation) + return; + + _launch_animation = animation; +} + +Launcher::LaunchAnimation +Launcher::GetLaunchAnimation () +{ + return _launch_animation; +} + +void +Launcher::SetUrgentAnimation (UrgentAnimation animation) +{ + if (_urgent_animation == animation) + return; + + _urgent_animation = animation; +} + +Launcher::UrgentAnimation +Launcher::GetUrgentAnimation () +{ + return _urgent_animation; +} + void Launcher::EnsureHoverState () { @@ -1121,6 +1232,11 @@ void Launcher::SetModel (LauncherModel *model) _model->order_changed.connect (sigc::mem_fun (this, &Launcher::OnOrderChanged)); } +LauncherModel* Launcher::GetModel () +{ + return _model; +} + void Launcher::OnIconNeedsRedraw (LauncherIcon *icon) { EnsureAnimation(); @@ -1148,12 +1264,6 @@ void Launcher::RenderIndicators (nux::GraphicsEngine& GfxContext, if (running > 0) { - if (!m_RunningIndicator) - { - GdkPixbuf *pbuf = gdk_pixbuf_new_from_file (PKGDATADIR"/running_indicator.png", NULL); - m_RunningIndicator = nux::CreateTextureFromPixbuf (pbuf); - g_object_unref (pbuf); - } nux::TexCoordXForm texxform; nux::Color color = nux::Color::LightGrey; @@ -1161,53 +1271,58 @@ void Launcher::RenderIndicators (nux::GraphicsEngine& GfxContext, if (arg.running_colored) color = nux::Color::SkyBlue; + nux::BaseTexture *texture; + std::vector<int> markers; - if (running == 1) + + /*if (!arg.running_on_viewport) { markers.push_back (markerCenter); + texture = _arrow_empty_ltr; + } + else*/ if (running == 1) + { + markers.push_back (markerCenter); + texture = _arrow_ltr; } else if (running == 2) { markers.push_back (markerCenter - 2); markers.push_back (markerCenter + 2); + texture = _pip_ltr; } else { markers.push_back (markerCenter - 4); markers.push_back (markerCenter); markers.push_back (markerCenter + 4); + texture = _pip_ltr; } std::vector<int>::iterator it; for (it = markers.begin (); it != markers.end (); it++) { int center = *it; - GfxContext.QRP_GLSL_1Tex (geo.x, - center - (m_RunningIndicator->GetHeight () / 2), - (float) m_RunningIndicator->GetWidth(), - (float) m_RunningIndicator->GetHeight(), - m_RunningIndicator->GetDeviceTexture(), - texxform, - color); + GfxContext.QRP_1Tex (geo.x, + center - (texture->GetHeight () / 2), + (float) texture->GetWidth(), + (float) texture->GetHeight(), + texture->GetDeviceTexture(), + texxform, + color); } } if (active > 0) { - if (!m_ActiveIndicator) - { - GdkPixbuf *pbuf = gdk_pixbuf_new_from_file (PKGDATADIR"/focused_indicator.png", NULL); - m_ActiveIndicator = nux::CreateTextureFromPixbuf (pbuf); - g_object_unref (pbuf); - } nux::TexCoordXForm texxform; nux::Color color = nux::Color::LightGrey; - GfxContext.QRP_GLSL_1Tex ((geo.x + geo.width) - m_ActiveIndicator->GetWidth (), - markerCenter - (m_ActiveIndicator->GetHeight () / 2), - (float) m_ActiveIndicator->GetWidth(), - (float) m_ActiveIndicator->GetHeight(), - m_ActiveIndicator->GetDeviceTexture(), + GfxContext.QRP_1Tex ((geo.x + geo.width) - _arrow_rtl->GetWidth (), + markerCenter - (_arrow_rtl->GetHeight () / 2), + (float) _arrow_rtl->GetWidth(), + (float) _arrow_rtl->GetHeight(), + _arrow_rtl->GetDeviceTexture(), texxform, color); } @@ -1228,7 +1343,7 @@ void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, nux::Matrix4 ProjectionMatrix; nux::Matrix4 ViewProjectionMatrix; - if(nux::Abs (arg.x_rotation) < 0.01f) + if(nux::Abs (arg.x_rotation) < 0.01f && nux::Abs (arg.y_rotation) < 0.01f && nux::Abs (arg.z_rotation) < 0.01f) icon->SetFiltering(GL_NEAREST, GL_NEAREST); else icon->SetFiltering(GL_LINEAR, GL_LINEAR); @@ -1256,7 +1371,7 @@ void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, v3.w = xform_coords[3].w ; float s0, t0, s1, t1, s2, t2, s3, t3; - nux::Color color = nux::Color::White; + nux::Color color = bkg_color; if (icon->GetResourceType () == nux::RTTEXTURERECTANGLE) { @@ -1275,10 +1390,10 @@ void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, float VtxBuffer[] = {// Perspective correct - v0.x, v0.y, 0.0f, 1.0f, s0/v0.w, t0/v0.w, 0.0f, 1.0f/v0.w, color.R(), color.G(), color.B(), color.A(), - v1.x, v1.y, 0.0f, 1.0f, s1/v1.w, t1/v1.w, 0.0f, 1.0f/v1.w, color.R(), color.G(), color.B(), color.A(), - v2.x, v2.y, 0.0f, 1.0f, s2/v2.w, t2/v2.w, 0.0f, 1.0f/v2.w, color.R(), color.G(), color.B(), color.A(), - v3.x, v3.y, 0.0f, 1.0f, s3/v3.w, t3/v3.w, 0.0f, 1.0f/v3.w, color.R(), color.G(), color.B(), color.A(), + v0.x, v0.y, 0.0f, 1.0f, s0/v0.w, t0/v0.w, 0.0f, 1.0f/v0.w, + v1.x, v1.y, 0.0f, 1.0f, s1/v1.w, t1/v1.w, 0.0f, 1.0f/v1.w, + v2.x, v2.y, 0.0f, 1.0f, s2/v2.w, t2/v2.w, 0.0f, 1.0f/v2.w, + v3.x, v3.y, 0.0f, 1.0f, s3/v3.w, t3/v3.w, 0.0f, 1.0f/v3.w, }; CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); @@ -1290,7 +1405,7 @@ void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, int VertexColorLocation; int FragmentColor; - if(!USE_ARB_SHADERS) + if(nux::GetGraphicsEngine ().UsingGLSLCodePath ()) { _shader_program_uv_persp_correction->Begin(); @@ -1298,7 +1413,7 @@ void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, VertexLocation = _shader_program_uv_persp_correction->GetAttributeLocation("iVertex"); TextureCoord0Location = _shader_program_uv_persp_correction->GetAttributeLocation("iTexCoord0"); VertexColorLocation = _shader_program_uv_persp_correction->GetAttributeLocation("iColor"); - FragmentColor = _shader_program_uv_persp_correction->GetUniformLocationARB ("color"); + FragmentColor = _shader_program_uv_persp_correction->GetUniformLocationARB ("color0"); nux::GetGraphicsEngine ().SetTexture(GL_TEXTURE0, icon); @@ -1324,23 +1439,23 @@ void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, } CHECKGL( glEnableVertexAttribArrayARB(VertexLocation) ); - CHECKGL( glVertexAttribPointerARB((GLuint)VertexLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer) ); + CHECKGL( glVertexAttribPointerARB((GLuint)VertexLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer) ); if(TextureCoord0Location != -1) { CHECKGL( glEnableVertexAttribArrayARB(TextureCoord0Location) ); - CHECKGL( glVertexAttribPointerARB((GLuint)TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 4) ); + CHECKGL( glVertexAttribPointerARB((GLuint)TextureCoord0Location, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 4) ); } - if(VertexColorLocation != -1) - { - CHECKGL( glEnableVertexAttribArrayARB(VertexColorLocation) ); - CHECKGL( glVertexAttribPointerARB((GLuint)VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8) ); - } +// if(VertexColorLocation != -1) +// { +// CHECKGL( glEnableVertexAttribArrayARB(VertexColorLocation) ); +// CHECKGL( glVertexAttribPointerARB((GLuint)VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 32, VtxBuffer + 8) ); +// } bkg_color.SetAlpha (bkg_color.A () * alpha); - if(!USE_ARB_SHADERS) + if(nux::GetGraphicsEngine ().UsingGLSLCodePath ()) { CHECKGL ( glUniform4fARB (FragmentColor, bkg_color.R(), bkg_color.G(), bkg_color.B(), bkg_color.A() ) ); nux::GetGraphicsEngine ().SetTexture(GL_TEXTURE0, icon); @@ -1357,10 +1472,10 @@ void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, CHECKGL( glDisableVertexAttribArrayARB(VertexLocation) ); if(TextureCoord0Location != -1) CHECKGL( glDisableVertexAttribArrayARB(TextureCoord0Location) ); - if(VertexColorLocation != -1) - CHECKGL( glDisableVertexAttribArrayARB(VertexColorLocation) ); +// if(VertexColorLocation != -1) +// CHECKGL( glDisableVertexAttribArrayARB(VertexColorLocation) ); - if(!USE_ARB_SHADERS) + if(nux::GetGraphicsEngine ().UsingGLSLCodePath ()) { _shader_program_uv_persp_correction->End(); } @@ -1372,6 +1487,10 @@ void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, void Launcher::DrawRenderArg (nux::GraphicsEngine& GfxContext, RenderArg const &arg, nux::Geometry geo) { + // This check avoids a crash when the icon is not available on the system. + if (arg.icon->TextureForSize (_icon_image_size) == 0) + return; + GfxContext.GetRenderStates ().SetSeparateBlend (true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, @@ -1890,7 +2009,7 @@ LauncherIcon* Launcher::MouseIconIntersection (int x, int y) // Because of the way icons fold and stack on one another, we must proceed in 2 steps. for (rev_it = _model->rbegin (); rev_it != _model->rend (); rev_it++) { - if ((*rev_it)->_folding_angle < 0.0f || !(*rev_it)->GetQuirk (LAUNCHER_ICON_QUIRK_VISIBLE)) + if ((*rev_it)->_folding_angle < 0.0f || !(*rev_it)->GetQuirk (LauncherIcon::QUIRK_VISIBLE)) continue; nux::Point2 screen_coord [4]; @@ -1906,7 +2025,7 @@ LauncherIcon* Launcher::MouseIconIntersection (int x, int y) for (it = _model->begin(); it != _model->end (); it++) { - if ((*it)->_folding_angle >= 0.0f || !(*it)->GetQuirk (LAUNCHER_ICON_QUIRK_VISIBLE)) + if ((*it)->_folding_angle >= 0.0f || !(*it)->GetQuirk (LauncherIcon::QUIRK_VISIBLE)) continue; nux::Point2 screen_coord [4]; @@ -2198,10 +2317,10 @@ Launcher::RenderProgressToTexture (nux::GraphicsEngine& GfxContext, nux::Intrusi // left door GfxContext.PushClippingRectangle(nux::Geometry (left_edge, 0, half_size, height)); - GfxContext.QRP_GLSL_1Tex (left_edge, progress_y, progress_width, progress_height, + GfxContext.QRP_1Tex (left_edge, progress_y, progress_width, progress_height, _progress_bar_trough->GetDeviceTexture (), texxform, nux::Color::White); - GfxContext.QRP_GLSL_1Tex (left_edge + fill_offset, fill_y, fill_width, fill_height, + GfxContext.QRP_1Tex (left_edge + fill_offset, fill_y, fill_width, fill_height, _progress_bar_fill->GetDeviceTexture (), texxform, nux::Color::White); GfxContext.PopClippingRectangle (); @@ -2210,10 +2329,10 @@ Launcher::RenderProgressToTexture (nux::GraphicsEngine& GfxContext, nux::Intrusi // right door GfxContext.PushClippingRectangle(nux::Geometry (left_edge + half_size, 0, half_size, height)); - GfxContext.QRP_GLSL_1Tex (right_edge - progress_width, progress_y, progress_width, progress_height, + GfxContext.QRP_1Tex (right_edge - progress_width, progress_y, progress_width, progress_height, _progress_bar_trough->GetDeviceTexture (), texxform, nux::Color::White); - GfxContext.QRP_GLSL_1Tex (right_edge - progress_width + fill_offset, fill_y, fill_width, fill_height, + GfxContext.QRP_1Tex (right_edge - progress_width + fill_offset, fill_y, fill_width, fill_height, _progress_bar_fill->GetDeviceTexture (), texxform, nux::Color::White); GfxContext.PopClippingRectangle (); diff --git a/src/Launcher.h b/src/Launcher.h index b759683c5..0da4e5494 100644 --- a/src/Launcher.h +++ b/src/Launcher.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -25,6 +26,7 @@ #include <Nux/View.h> #include <Nux/BaseWindow.h> + #include "Introspectable.h" #include "LauncherIcon.h" #include "LauncherDragWindow.h" @@ -32,12 +34,33 @@ #include "Nux/TimerProc.h" #include "PluginAdapter.h" +#define ANIM_DURATION_SHORT 125 +#define ANIM_DURATION 200 +#define ANIM_DURATION_LONG 350 + class LauncherModel; class QuicklistView; +class LauncherIcon; +class LauncherDragWindow; class Launcher : public Introspectable, public nux::View { + NUX_DECLARE_OBJECT_TYPE (Launcher, nux::View); public: + typedef enum + { + LAUNCH_ANIMATION_NONE, + LAUNCH_ANIMATION_PULSE, + LAUNCH_ANIMATION_BLINK, + } LaunchAnimation; + + typedef enum + { + URGENT_ANIMATION_NONE, + URGENT_ANIMATION_PULSE, + URGENT_ANIMATION_WIGGLE, + } UrgentAnimation; + Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_PROTO); ~Launcher(); @@ -48,18 +71,35 @@ public: LauncherIcon* GetActiveTooltipIcon() {return m_ActiveTooltipIcon;} LauncherIcon* GetActiveMenuIcon() {return m_ActiveMenuIcon;} + LauncherIcon* GetLastSpreadIcon() {return m_LastSpreadIcon;} + void SetLastSpreadIcon(LauncherIcon *i) {m_LastSpreadIcon = i;} void SetIconSize(int tile_size, int icon_size); void SetModel (LauncherModel *model); + LauncherModel* GetModel (); void SetFloating (bool floating); void SetAutohide (bool autohide, nux::View *show_trigger); bool AutohideEnabled (); + + void ForceShowLauncherStart (); + void ForceShowLauncherEnd (); + + void SetBacklightAlwaysOn (bool always_on); + bool GetBacklightAlwaysOn (); + + void SetLaunchAnimation (LaunchAnimation animation); + LaunchAnimation GetLaunchAnimation (); + + void SetUrgentAnimation (UrgentAnimation animation); + UrgentAnimation GetUrgentAnimation (); nux::BaseWindow* GetParent () { return _parent; }; + static void SetTimeStruct (struct timespec *timer, struct timespec *sister = 0, int sister_relation = 0); + virtual void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); virtual void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); virtual void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); @@ -81,12 +121,6 @@ protected: private: typedef enum { - LAUNCHER_FOLDED, - LAUNCHER_UNFOLDED - } LauncherState; - - typedef enum - { ACTION_NONE, ACTION_DRAG_LAUNCHER, ACTION_DRAG_ICON, @@ -108,6 +142,7 @@ private: float progress_bias; bool running_arrow; bool running_colored; + bool running_on_viewport; bool active_arrow; bool active_colored; bool skip; @@ -115,7 +150,7 @@ private: int window_indicators; } RenderArg; - void OnWindowMaybeIntellihide (CompWindow *window); + void OnWindowMaybeIntellihide (guint32 xid); static gboolean AnimationTimeout (gpointer data); static gboolean OnAutohideTimeout (gpointer data); @@ -131,7 +166,6 @@ private: bool IconNeedsAnimation (LauncherIcon *icon, struct timespec const ¤t); bool AnimationInProgress (); - void SetTimeStruct (struct timespec *timer, struct timespec *sister = 0, int sister_relation = 0); void EnsureHoverState (); void EnsureHiddenState (); @@ -149,6 +183,8 @@ private: float IconUrgentProgress (LauncherIcon *icon, struct timespec const ¤t); float IconShimmerProgress (LauncherIcon *icon, struct timespec const ¤t); float IconUrgentPulseValue (LauncherIcon *icon, struct timespec const ¤t); + float IconUrgentWiggleValue (LauncherIcon *icon, struct timespec const ¤t); + float IconStartingBlinkValue (LauncherIcon *icon, struct timespec const ¤t); float IconStartingPulseValue (LauncherIcon *icon, struct timespec const ¤t); float IconBackgroundIntensity (LauncherIcon *icon, struct timespec const ¤t); float IconProgressBias (LauncherIcon *icon, struct timespec const ¤t); @@ -225,7 +261,7 @@ private: LauncherIcon* m_ActiveTooltipIcon; LauncherIcon* m_ActiveMenuIcon; - + LauncherIcon* m_LastSpreadIcon; QuicklistView* _active_quicklist; @@ -235,8 +271,10 @@ private: bool _hidden; bool _mouse_inside_launcher; bool _mouse_inside_trigger; + bool _force_show_launcher; bool _window_over_launcher; bool _render_drag_window; + bool _backlight_always_on; float _folded_angle; float _neg_folded_angle; @@ -244,8 +282,9 @@ private: float _launcher_top_y; float _launcher_bottom_y; - LauncherState _launcher_state; LauncherActionState _launcher_action_state; + LaunchAnimation _launch_animation; + UrgentAnimation _urgent_animation; LauncherIcon* _icon_under_mouse; LauncherIcon* _icon_mouse_down; @@ -269,6 +308,13 @@ private: nux::BaseTexture* _progress_bar_trough; nux::BaseTexture* _progress_bar_fill; + nux::BaseTexture* _pip_ltr; + nux::BaseTexture* _pip_rtl; + nux::BaseTexture* _arrow_ltr; + nux::BaseTexture* _arrow_rtl; + nux::BaseTexture* _arrow_empty_ltr; + nux::BaseTexture* _arrow_empty_rtl; + nux::IntrusiveSP<nux::IOpenGLBaseTexture> _offscreen_drag_texture; nux::IntrusiveSP<nux::IOpenGLBaseTexture> _offscreen_progress_texture; @@ -279,8 +325,6 @@ private: nux::Point2 _mouse_position; nux::IntrusiveSP<nux::IOpenGLShaderProgram> _shader_program_uv_persp_correction; nux::IntrusiveSP<nux::IOpenGLAsmShaderProgram> _AsmShaderProg; - nux::BaseTexture* m_RunningIndicator; - nux::BaseTexture* m_ActiveIndicator; nux::AbstractPaintLayer* m_BackgroundLayer; nux::BaseWindow* _parent; nux::View* _autohide_trigger; diff --git a/src/LauncherController.cpp b/src/LauncherController.cpp index c295554c7..cca2802bd 100644 --- a/src/LauncherController.cpp +++ b/src/LauncherController.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -38,7 +39,7 @@ LauncherController::LauncherController(Launcher* launcher, CompScreen *screen, n _launcher->SetModel (_model); _favorite_store = FavoriteStore::GetDefault (); - g_timeout_add (5000, (GSourceFunc) &LauncherController::BamfTimerCallback, this); + g_timeout_add (500, (GSourceFunc) &LauncherController::BamfTimerCallback, this); InsertExpoAction (); InsertTrash (); @@ -193,9 +194,9 @@ LauncherController::InsertExpoAction () expoIcon->SetTooltipText ("Workspace Switcher"); expoIcon->SetIconName ("workspace-switcher"); - expoIcon->SetQuirk (LAUNCHER_ICON_QUIRK_VISIBLE, true); - expoIcon->SetQuirk (LAUNCHER_ICON_QUIRK_RUNNING, false); - expoIcon->SetIconType (LAUNCHER_ICON_TYPE_END); + expoIcon->SetQuirk (LauncherIcon::QUIRK_VISIBLE, true); + expoIcon->SetQuirk (LauncherIcon::QUIRK_RUNNING, false); + expoIcon->SetIconType (LauncherIcon::TYPE_END); expoIcon->MouseClick.connect (sigc::mem_fun (this, &LauncherController::OnExpoClicked)); @@ -253,7 +254,7 @@ LauncherController::OnViewOpened (BamfMatcher *matcher, BamfView *view, gpointer app = BAMF_APPLICATION (view); BamfLauncherIcon *icon = new BamfLauncherIcon (self->_launcher, app, self->_screen); - icon->SetIconType (LAUNCHER_ICON_TYPE_APPLICATION); + icon->SetIconType (LauncherIcon::TYPE_APPLICATION); icon->SetSortPriority (self->_sort_priority++); self->RegisterIcon (icon); @@ -279,7 +280,7 @@ LauncherController::CreateFavorite (const char *file_path) bamf_view_set_sticky (BAMF_VIEW (app), true); icon = new BamfLauncherIcon (_launcher, app, _screen); - icon->SetIconType (LAUNCHER_ICON_TYPE_APPLICATION); + icon->SetIconType (LauncherIcon::TYPE_APPLICATION); icon->SetSortPriority (_sort_priority++); return icon; diff --git a/src/LauncherController.h b/src/LauncherController.h index a63afd150..c963246e9 100644 --- a/src/LauncherController.h +++ b/src/LauncherController.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/LauncherDragWindow.cpp b/src/LauncherDragWindow.cpp index 7fe189e63..3e5302e1b 100644 --- a/src/LauncherDragWindow.cpp +++ b/src/LauncherDragWindow.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -105,7 +106,7 @@ LauncherDragWindow::DrawContent (nux::GraphicsEngine& GfxContext, bool force_dra nux::TexCoordXForm texxform; texxform.FlipVCoord (true); - GfxContext.QRP_GLSL_1Tex (0, + GfxContext.QRP_1Tex (0, 0, _icon->GetWidth(), _icon->GetHeight(), diff --git a/src/LauncherDragWindow.h b/src/LauncherDragWindow.h index 9e4853834..107fa600d 100644 --- a/src/LauncherDragWindow.h +++ b/src/LauncherDragWindow.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/LauncherIcon.cpp b/src/LauncherIcon.cpp index 8471a3d2b..bb85dc6d0 100644 --- a/src/LauncherIcon.cpp +++ b/src/LauncherIcon.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -40,6 +41,8 @@ #define DEFAULT_ICON "application-default-icon" +NUX_IMPLEMENT_OBJECT_TYPE (LauncherIcon); + nux::Tooltip *LauncherIcon::_current_tooltip = 0; QuicklistView *LauncherIcon::_current_quicklist = 0; @@ -49,7 +52,7 @@ LauncherIcon::LauncherIcon(Launcher* launcher) _launcher = launcher; m_TooltipText = "blank"; - for (int i = 0; i < LAUNCHER_ICON_QUIRK_LAST; i++) + for (int i = 0; i < QUIRK_LAST; i++) { _quirks[i] = 0; _quirk_times[i].tv_sec = 0; @@ -62,8 +65,9 @@ LauncherIcon::LauncherIcon(Launcher* launcher) _glow_color = nux::Color::White; _mouse_inside = false; + _has_visible_window = false; _tooltip = new nux::Tooltip (); - _icon_type = LAUNCHER_ICON_TYPE_NONE; + _icon_type = TYPE_NONE; _sort_priority = 0; _quicklist = new QuicklistView (); @@ -97,6 +101,12 @@ LauncherIcon::~LauncherIcon() _center_stabilize_handle = 0; } +bool +LauncherIcon::HasVisibleWindow () +{ + return _has_visible_window; +} + const gchar * LauncherIcon::GetName () { @@ -114,11 +124,11 @@ LauncherIcon::AddProperties (GVariantBuilder *builder) g_variant_builder_add (builder, "{sv}", "tooltip-text", g_variant_new_string (m_TooltipText.GetTCharPtr ())); g_variant_builder_add (builder, "{sv}", "sort-priority", g_variant_new_int32 (_sort_priority)); - g_variant_builder_add (builder, "{sv}", "quirk-active", g_variant_new_boolean (GetQuirk (LAUNCHER_ICON_QUIRK_ACTIVE))); - g_variant_builder_add (builder, "{sv}", "quirk-visible", g_variant_new_boolean (GetQuirk (LAUNCHER_ICON_QUIRK_VISIBLE))); - g_variant_builder_add (builder, "{sv}", "quirk-urgent", g_variant_new_boolean (GetQuirk (LAUNCHER_ICON_QUIRK_URGENT))); - g_variant_builder_add (builder, "{sv}", "quirk-running", g_variant_new_boolean (GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING))); - g_variant_builder_add (builder, "{sv}", "quirk-presented", g_variant_new_boolean (GetQuirk (LAUNCHER_ICON_QUIRK_PRESENTED))); + g_variant_builder_add (builder, "{sv}", "quirk-active", g_variant_new_boolean (GetQuirk (QUIRK_ACTIVE))); + g_variant_builder_add (builder, "{sv}", "quirk-visible", g_variant_new_boolean (GetQuirk (QUIRK_VISIBLE))); + g_variant_builder_add (builder, "{sv}", "quirk-urgent", g_variant_new_boolean (GetQuirk (QUIRK_URGENT))); + g_variant_builder_add (builder, "{sv}", "quirk-running", g_variant_new_boolean (GetQuirk (QUIRK_RUNNING))); + g_variant_builder_add (builder, "{sv}", "quirk-presented", g_variant_new_boolean (GetQuirk (QUIRK_PRESENTED))); } nux::Color LauncherIcon::BackgroundColor () @@ -178,8 +188,8 @@ void LauncherIcon::ColorForIcon (GdkPixbuf *pixbuf, nux::Color &background, nux: nux::RGBtoHSV (r, g, b, h, s, v); if (s > .15f) - s = 0.4f; - v = .85f; + s = 0.65f; + v = 0.90f; nux::HSVtoRGB (r, g, b, h, s, v); background = nux::Color (r, g, b); @@ -422,14 +432,24 @@ void LauncherIcon::SaveCenter () { _saved_center = _center; - UpdateQuirkTime (LAUNCHER_ICON_QUIRK_CENTER_SAVED); + UpdateQuirkTime (QUIRK_CENTER_SAVED); +} + +void +LauncherIcon::SetHasVisibleWindow (bool val) +{ + if (_has_visible_window == val) + return; + + _has_visible_window = val; + needs_redraw.emit (this); } gboolean LauncherIcon::OnPresentTimeout (gpointer data) { LauncherIcon *self = (LauncherIcon*) data; - if (!self->GetQuirk (LAUNCHER_ICON_QUIRK_PRESENTED)) + if (!self->GetQuirk (QUIRK_PRESENTED)) return false; self->_present_time_handle = 0; @@ -446,26 +466,26 @@ float LauncherIcon::PresentUrgency () void LauncherIcon::Present (float present_urgency, int length) { - if (GetQuirk (LAUNCHER_ICON_QUIRK_PRESENTED)) + if (GetQuirk (QUIRK_PRESENTED)) return; if (length >= 0) _present_time_handle = g_timeout_add (length, &LauncherIcon::OnPresentTimeout, this); _present_urgency = CLAMP (present_urgency, 0.0f, 1.0f); - SetQuirk (LAUNCHER_ICON_QUIRK_PRESENTED, true); + SetQuirk (QUIRK_PRESENTED, true); } void LauncherIcon::Unpresent () { - if (!GetQuirk (LAUNCHER_ICON_QUIRK_PRESENTED)) + if (!GetQuirk (QUIRK_PRESENTED)) return; if (_present_time_handle > 0) g_source_remove (_present_time_handle); - SetQuirk (LAUNCHER_ICON_QUIRK_PRESENTED, false); + SetQuirk (QUIRK_PRESENTED, false); } void @@ -481,12 +501,12 @@ LauncherIcon::SetRelatedWindows (int windows) void LauncherIcon::Remove () { - SetQuirk (LAUNCHER_ICON_QUIRK_VISIBLE, false); + SetQuirk (QUIRK_VISIBLE, false); remove.emit (this); } void -LauncherIcon::SetIconType (LauncherIconType type) +LauncherIcon::SetIconType (IconType type) { _icon_type = type; } @@ -503,32 +523,35 @@ LauncherIcon::SortPriority () return _sort_priority; } -LauncherIconType +LauncherIcon::IconType LauncherIcon::Type () { return _icon_type; } bool -LauncherIcon::GetQuirk (LauncherIconQuirk quirk) +LauncherIcon::GetQuirk (LauncherIcon::Quirk quirk) { return _quirks[quirk]; } void -LauncherIcon::SetQuirk (LauncherIconQuirk quirk, bool value) +LauncherIcon::SetQuirk (LauncherIcon::Quirk quirk, bool value) { if (_quirks[quirk] == value) return; _quirks[quirk] = value; - clock_gettime (CLOCK_MONOTONIC, &(_quirk_times[quirk])); + if (quirk == QUIRK_VISIBLE) + Launcher::SetTimeStruct (&(_quirk_times[quirk]), &(_quirk_times[quirk]), ANIM_DURATION_SHORT); + else + clock_gettime (CLOCK_MONOTONIC, &(_quirk_times[quirk])); needs_redraw.emit (this); // Present on urgent as a general policy - if (quirk == LAUNCHER_ICON_QUIRK_VISIBLE && value) + if (quirk == QUIRK_VISIBLE && value) Present (0.5f, 1500); - if (quirk == LAUNCHER_ICON_QUIRK_URGENT && value) + if (quirk == QUIRK_URGENT && value) Present (0.5f, 1500); } @@ -545,7 +568,7 @@ LauncherIcon::OnDelayedUpdateTimeout (gpointer data) } void -LauncherIcon::UpdateQuirkTimeDelayed (guint ms, LauncherIconQuirk quirk) +LauncherIcon::UpdateQuirkTimeDelayed (guint ms, LauncherIcon::Quirk quirk) { DelayedUpdateArg *arg = new DelayedUpdateArg (); arg->self = this; @@ -555,21 +578,21 @@ LauncherIcon::UpdateQuirkTimeDelayed (guint ms, LauncherIconQuirk quirk) } void -LauncherIcon::UpdateQuirkTime (LauncherIconQuirk quirk) +LauncherIcon::UpdateQuirkTime (LauncherIcon::Quirk quirk) { clock_gettime (CLOCK_MONOTONIC, &(_quirk_times[quirk])); needs_redraw.emit (this); } void -LauncherIcon::ResetQuirkTime (LauncherIconQuirk quirk) +LauncherIcon::ResetQuirkTime (LauncherIcon::Quirk quirk) { _quirk_times[quirk].tv_sec = 0; _quirk_times[quirk].tv_nsec = 0; } struct timespec -LauncherIcon::GetQuirkTime (LauncherIconQuirk quirk) +LauncherIcon::GetQuirkTime (LauncherIcon::Quirk quirk) { return _quirk_times[quirk]; } diff --git a/src/LauncherIcon.h b/src/LauncherIcon.h index 1ba0821cb..989adb54a 100644 --- a/src/LauncherIcon.h +++ b/src/LauncherIcon.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -36,40 +37,43 @@ #include "Tooltip.h" #include "QuicklistView.h" #include "Introspectable.h" +#include "Launcher.h" class Launcher; class QuicklistView; -typedef enum -{ - LAUNCHER_ICON_TYPE_NONE, - LAUNCHER_ICON_TYPE_BEGIN, - LAUNCHER_ICON_TYPE_FAVORITE, - LAUNCHER_ICON_TYPE_APPLICATION, - LAUNCHER_ICON_TYPE_PLACE, - LAUNCHER_ICON_TYPE_DEVICE, - LAUNCHER_ICON_TYPE_TRASH, - LAUNCHER_ICON_TYPE_END, -} LauncherIconType; - -typedef enum -{ - LAUNCHER_ICON_QUIRK_VISIBLE, - LAUNCHER_ICON_QUIRK_ACTIVE, - LAUNCHER_ICON_QUIRK_RUNNING, - LAUNCHER_ICON_QUIRK_URGENT, - LAUNCHER_ICON_QUIRK_PRESENTED, - LAUNCHER_ICON_QUIRK_STARTING, - LAUNCHER_ICON_QUIRK_SHIMMER, - LAUNCHER_ICON_QUIRK_CENTER_SAVED, - LAUNCHER_ICON_QUIRK_PROGRESS, - - LAUNCHER_ICON_QUIRK_LAST, -} LauncherIconQuirk; class LauncherIcon : public Introspectable, public nux::InitiallyUnownedObject, public sigc::trackable { + NUX_DECLARE_OBJECT_TYPE (LauncherIcon, nux::InitiallyUnownedObject); public: + typedef enum + { + TYPE_NONE, + TYPE_BEGIN, + TYPE_FAVORITE, + TYPE_APPLICATION, + TYPE_PLACE, + TYPE_DEVICE, + TYPE_TRASH, + TYPE_END, + } IconType; + + typedef enum + { + QUIRK_VISIBLE, + QUIRK_ACTIVE, + QUIRK_RUNNING, + QUIRK_URGENT, + QUIRK_PRESENTED, + QUIRK_STARTING, + QUIRK_SHIMMER, + QUIRK_CENTER_SAVED, + QUIRK_PROGRESS, + + QUIRK_LAST, + } Quirk; + LauncherIcon(Launcher* launcher); virtual ~LauncherIcon(); @@ -93,17 +97,19 @@ public: int RelatedWindows (); + bool HasVisibleWindow (); + float PresentUrgency (); float GetProgress (); - bool GetQuirk (LauncherIconQuirk quirk); - struct timespec GetQuirkTime (LauncherIconQuirk quirk); + bool GetQuirk (Quirk quirk); + struct timespec GetQuirkTime (Quirk quirk); - LauncherIconType Type (); + IconType Type (); - nux::Color BackgroundColor (); - nux::Color GlowColor (); + virtual nux::Color BackgroundColor (); + virtual nux::Color GlowColor (); nux::BaseTexture * TextureForSize (int size); @@ -123,21 +129,23 @@ protected: const gchar * GetName (); void AddProperties (GVariantBuilder *builder); - void SetQuirk (LauncherIconQuirk quirk, bool value); + void SetQuirk (Quirk quirk, bool value); - void UpdateQuirkTimeDelayed (guint ms, LauncherIconQuirk quirk); - void UpdateQuirkTime (LauncherIconQuirk quirk); - void ResetQuirkTime (LauncherIconQuirk quirk); + void UpdateQuirkTimeDelayed (guint ms, Quirk quirk); + void UpdateQuirkTime (Quirk quirk); + void ResetQuirkTime (Quirk quirk); void SetRelatedWindows (int windows); void Remove (); void SetProgress (float progress); + void SetHasVisibleWindow (bool val); + void Present (float urgency, int length); void Unpresent (); - void SetIconType (LauncherIconType type); + void SetIconType (IconType type); void SetSortPriority (int priority); virtual std::list<DbusmenuMenuitem *> GetMenus (); @@ -171,7 +179,7 @@ private: typedef struct { LauncherIcon *self; - LauncherIconQuirk quirk; + Quirk quirk; } DelayedUpdateArg; static void ChildRealized (DbusmenuMenuitem *newitem, QuicklistView *quicklist); @@ -191,14 +199,15 @@ private: guint _present_time_handle; guint _center_stabilize_handle; bool _quicklist_is_initialized; + bool _has_visible_window; nux::Point3 _center; nux::Point3 _last_stable; nux::Point3 _saved_center; - LauncherIconType _icon_type; + IconType _icon_type; - bool _quirks[LAUNCHER_ICON_QUIRK_LAST]; - struct timespec _quirk_times[LAUNCHER_ICON_QUIRK_LAST]; + bool _quirks[QUIRK_LAST]; + struct timespec _quirk_times[QUIRK_LAST]; }; diff --git a/src/LauncherModel.cpp b/src/LauncherModel.cpp index 2ed6c3a7b..834a6e12e 100644 --- a/src/LauncherModel.cpp +++ b/src/LauncherModel.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -36,7 +37,7 @@ LauncherModel::~LauncherModel() bool LauncherModel::IconShouldShelf (LauncherIcon *icon) { - return icon->Type () == LAUNCHER_ICON_TYPE_TRASH; + return icon->Type () == LauncherIcon::TYPE_TRASH; } void diff --git a/src/LauncherModel.h b/src/LauncherModel.h index 2c5da9e2c..a63138e73 100644 --- a/src/LauncherModel.h +++ b/src/LauncherModel.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/PanelHomeButton.cpp b/src/PanelHomeButton.cpp index 711a0d824..119be9bf5 100644 --- a/src/PanelHomeButton.cpp +++ b/src/PanelHomeButton.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/PanelHomeButton.h b/src/PanelHomeButton.h index 03de813f6..c5f7c36f2 100644 --- a/src/PanelHomeButton.h +++ b/src/PanelHomeButton.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/PanelIndicatorObjectEntryView.cpp b/src/PanelIndicatorObjectEntryView.cpp index a43f0dadd..51a4d78f7 100644 --- a/src/PanelIndicatorObjectEntryView.cpp +++ b/src/PanelIndicatorObjectEntryView.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -44,6 +45,7 @@ PanelIndicatorObjectEntryView::PanelIndicatorObjectEntryView (IndicatorObjectEnt _proxy->updated.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::Refresh)); InputArea::OnMouseDown.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::OnMouseDown)); + InputArea::OnMouseWheel.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::OnMouseWheel)); Refresh (); } @@ -75,6 +77,12 @@ PanelIndicatorObjectEntryView::OnMouseDown (int x, int y, long button_flags, lon } void +PanelIndicatorObjectEntryView::OnMouseWheel (int x, int y, int delta, unsigned long mouse_state, unsigned long key_state) +{ + _proxy->Scroll (delta); +} + +void PanelIndicatorObjectEntryView::Activate () { _proxy->ShowMenu (GetGeometry ().x + 1, //cairo translation FIXME: Make this into one function @@ -253,9 +261,10 @@ PanelIndicatorObjectEntryView::Refresh () // The texture layer has been cloned by this object when calling SetPaintLayer. It is safe to delete it now. delete texture_layer; - + NeedRedraw (); + refreshed.emit (this); if (label) g_free (label); } diff --git a/src/PanelIndicatorObjectEntryView.h b/src/PanelIndicatorObjectEntryView.h index 2bc8971f8..db51963c3 100644 --- a/src/PanelIndicatorObjectEntryView.h +++ b/src/PanelIndicatorObjectEntryView.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -40,6 +41,7 @@ public: void Refresh (); void OnMouseDown (int x, int y, long button_flags, long key_flags); + void OnMouseWheel (int x, int y, int delta, unsigned long mouse_state, unsigned long key_state); void Activate (); void OnActiveChanged (bool is_active); @@ -47,6 +49,7 @@ public: void AddProperties (GVariantBuilder *builder); sigc::signal<void, PanelIndicatorObjectEntryView *, bool> active_changed; + sigc::signal<void, PanelIndicatorObjectEntryView *> refreshed; public: IndicatorObjectEntryProxy *_proxy; diff --git a/src/PanelIndicatorObjectView.cpp b/src/PanelIndicatorObjectView.cpp index a3a9f55cb..e8e3348ae 100644 --- a/src/PanelIndicatorObjectView.cpp +++ b/src/PanelIndicatorObjectView.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/PanelIndicatorObjectView.h b/src/PanelIndicatorObjectView.h index 0c5baf4a0..346b95a68 100644 --- a/src/PanelIndicatorObjectView.h +++ b/src/PanelIndicatorObjectView.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/PanelMenuView.cpp b/src/PanelMenuView.cpp index 0199f1b1c..8e0ad2dcf 100644 --- a/src/PanelMenuView.cpp +++ b/src/PanelMenuView.cpp @@ -74,7 +74,16 @@ PanelMenuView::PanelMenuView () _window_buttons->restore_clicked.connect (sigc::mem_fun (this, &PanelMenuView::OnRestoreClicked)); _window_buttons->redraw_signal.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowButtonsRedraw)); + _panel_titlebar_grab_area = new PanelTitlebarGrabArea (); + _panel_titlebar_grab_area->mouse_down.connect (sigc::mem_fun (this, &PanelMenuView::OnMaximizedGrab)); + win_manager = WindowManager::Default (); + + win_manager->window_minimized.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowMinimized)); + win_manager->window_unminimized.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowUnminimized)); + win_manager->initiate_spread.connect (sigc::mem_fun (this, &PanelMenuView::OnSpreadInitiate)); + win_manager->terminate_spread.connect (sigc::mem_fun (this, &PanelMenuView::OnSpreadTerminate)); + win_manager->window_maximized.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowMaximized)); win_manager->window_restored.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowRestored)); win_manager->window_unmapped.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowUnmapped)); @@ -91,6 +100,7 @@ PanelMenuView::~PanelMenuView () _menu_layout->UnReference (); _window_buttons->UnReference (); + _panel_titlebar_grab_area->UnReference (); } void @@ -122,7 +132,10 @@ PanelMenuView::ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long Proces { if (_is_inside != true) { - _is_inside = true; + if (_is_grabbed) + _is_grabbed = false; + else + _is_inside = true; FullRedraw (); } } @@ -136,7 +149,11 @@ PanelMenuView::ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long Proces } if (_is_maximized) + { ret = _window_buttons->ProcessEvent (ievent, ret, ProcessEventInfo); + ret = _panel_titlebar_grab_area->OnEvent (ievent, ret, ProcessEventInfo); + } + ret = _menu_layout->ProcessEvent (ievent, ret, ProcessEventInfo); return ret; @@ -145,19 +162,30 @@ PanelMenuView::ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long Proces long PanelMenuView::PostLayoutManagement (long LayoutResult) { long res = View::PostLayoutManagement (LayoutResult); - int w = _window_buttons->GetContentWidth (); + int old_window_buttons_w, new_window_buttons_w; + int old_menu_area_w, new_menu_area_w; nux::Geometry geo = GetGeometry (); - _window_buttons->SetGeometry (geo.x + PADDING, geo.y, w, geo.height); + old_window_buttons_w = _window_buttons->GetContentWidth (); + _window_buttons->SetGeometry (geo.x + PADDING, geo.y, old_window_buttons_w, geo.height); _window_buttons->ComputeLayout2 (); + new_window_buttons_w = _window_buttons->GetContentWidth (); + /* Explicitly set the size and position of the widgets */ - geo.x += PADDING + w + PADDING; - geo.width -= PADDING + w + PADDING; + geo.x += PADDING + new_window_buttons_w + PADDING; + geo.width -= PADDING + new_window_buttons_w + PADDING; - _menu_layout->SetGeometry (geo.x, geo.y, geo.width, geo.height); + old_menu_area_w = _menu_layout->GetContentWidth (); + _menu_layout->SetGeometry (geo.x, geo.y, old_menu_area_w, geo.height); _menu_layout->ComputeLayout2(); + new_menu_area_w = _menu_layout->GetContentWidth (); + + geo.x += new_menu_area_w; + geo.width -= new_menu_area_w; + + _panel_titlebar_grab_area->SetGeometry (geo.x, geo.y, geo.width, geo.height); Refresh (); @@ -185,7 +213,7 @@ PanelMenuView::Draw (nux::GraphicsEngine& GfxContext, bool force_draw) if (_is_maximized) { - if (!_is_inside) + if (!_is_inside && !_last_active_view) gPainter.PushDrawLayer (GfxContext, GetGeometry (), _title_layer); } else @@ -462,6 +490,13 @@ PanelMenuView::Refresh () g_free (label); } +/* The entry was refreshed - so relayout our panel */ +void +PanelMenuView::OnEntryRefreshed (PanelIndicatorObjectEntryView *view) +{ + ComputeChildLayout (); +} + void PanelMenuView::OnActiveChanged (PanelIndicatorObjectEntryView *view, bool is_active) @@ -475,6 +510,8 @@ PanelMenuView::OnActiveChanged (PanelIndicatorObjectEntryView *view, _last_active_view = NULL; } } + + Refresh (); FullRedraw (); } @@ -483,6 +520,7 @@ PanelMenuView::OnEntryAdded (IndicatorObjectEntryProxy *proxy) { PanelIndicatorObjectEntryView *view = new PanelIndicatorObjectEntryView (proxy); view->active_changed.connect (sigc::mem_fun (this, &PanelMenuView::OnActiveChanged)); + view->refreshed.connect (sigc::mem_fun (this, &PanelMenuView::OnEntryRefreshed)); _menu_layout->AddView (view, 0, nux::eCenter, nux::eFull); _menu_layout->SetContentDistribution (nux::eStackLeft); @@ -540,7 +578,11 @@ PanelMenuView::OnActiveWindowChanged (BamfView *old_view, if (BAMF_IS_WINDOW (new_view)) { BamfWindow *window = BAMF_WINDOW (new_view); - _is_maximized = WindowManager::Default ()->IsWindowMaximized (bamf_window_get_xid (window)); + guint32 xid = bamf_window_get_xid (window); + _is_maximized = WindowManager::Default ()->IsWindowMaximized (xid); + + if (_decor_map.find (xid) == _decor_map.end ()) + _decor_map[xid] = true; } Refresh (); @@ -548,6 +590,43 @@ PanelMenuView::OnActiveWindowChanged (BamfView *old_view, } void +PanelMenuView::OnSpreadInitiate (std::list <guint32> &windows) +{ + foreach (guint32 &xid, windows) + { + if (WindowManager::Default ()->IsWindowMaximized (xid)) + WindowManager::Default ()->Decorate (xid); + } +} + +void +PanelMenuView::OnSpreadTerminate (std::list <guint32> &windows) +{ + foreach (guint32 &xid, windows) + { + if (WindowManager::Default ()->IsWindowMaximized (xid)) + WindowManager::Default ()->Undecorate (xid); + } +} + +void +PanelMenuView::OnWindowMinimized (guint32 xid) +{ + + if (WindowManager::Default ()->IsWindowMaximized (xid)) + WindowManager::Default ()->Decorate (xid); +} + +void +PanelMenuView::OnWindowUnminimized (guint32 xid) +{ + if (WindowManager::Default ()->IsWindowMaximized (xid)) + { + WindowManager::Default ()->Undecorate (xid); + } +} + +void PanelMenuView::OnWindowUnmapped (guint32 xid) { _decor_map.erase (xid); @@ -633,6 +712,25 @@ PanelMenuView::OnWindowButtonsRedraw () FullRedraw (); } +void +PanelMenuView::OnMaximizedGrab (int x, int y) +{ + if (_is_maximized) + { + BamfWindow *window; + + window = bamf_matcher_get_active_window (_matcher); + if (BAMF_IS_WINDOW (window)) + { + _is_inside = false; + _is_grabbed = true; + Refresh (); + FullRedraw (); + WindowManager::Default ()->StartMove (bamf_window_get_xid (window), x, y); + } + } +} + // Introspectable const gchar * PanelMenuView::GetName () diff --git a/src/PanelMenuView.h b/src/PanelMenuView.h index 66f2f0f04..7c192137b 100644 --- a/src/PanelMenuView.h +++ b/src/PanelMenuView.h @@ -27,6 +27,8 @@ #include "PanelIndicatorObjectView.h" #include "StaticCairoText.h" #include "WindowButtons.h" +#include "PanelTitlebarGrabAreaView.h" +#include "PluginAdapter.h" #include <libbamf/libbamf.h> @@ -60,13 +62,20 @@ public: void OnEntryAdded (IndicatorObjectEntryProxy *proxy); void OnEntryMoved (IndicatorObjectEntryProxy *proxy); void OnEntryRemoved (IndicatorObjectEntryProxy *proxy); + void OnEntryRefreshed (PanelIndicatorObjectEntryView *view); void OnActiveChanged (PanelIndicatorObjectEntryView *view, bool is_active); void OnActiveWindowChanged (BamfView *old_view, BamfView *new_view); - - void OnWindowUnmapped (guint xid); + + void OnSpreadInitiate (std::list <guint32> &); + void OnSpreadTerminate (std::list <guint32> &); + void OnWindowMinimized (guint32 xid); + void OnWindowUnminimized (guint32 xid); + void OnWindowUnmapped (guint32 xid); void OnWindowMaximized (guint32 xid); void OnWindowRestored (guint32 xid); + void OnMaximizedGrab (int x, int y); + void Refresh (); void AllMenusClosed (); @@ -93,10 +102,12 @@ private: nux::BaseTexture *_title_tex; bool _is_inside; + bool _is_grabbed; bool _is_maximized; PanelIndicatorObjectEntryView *_last_active_view; - WindowButtons *_window_buttons; + WindowButtons * _window_buttons; + PanelTitlebarGrabArea * _panel_titlebar_grab_area; std::map<guint32, bool> _decor_map; }; diff --git a/src/PanelTitlebarGrabAreaView.cpp b/src/PanelTitlebarGrabAreaView.cpp new file mode 100644 index 000000000..2ed79e01c --- /dev/null +++ b/src/PanelTitlebarGrabAreaView.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2010 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com> + */ + +#include "Nux/Nux.h" +#include "Nux/HLayout.h" +#include "Nux/VLayout.h" +#include "Nux/Button.h" + +#include "NuxGraphics/GLThread.h" +#include "Nux/BaseWindow.h" +#include "Nux/WindowCompositor.h" + +#include "PanelTitlebarGrabAreaView.h" + +#include <glib.h> + +enum +{ + BUTTON_CLOSE=0, + BUTTON_MINIMISE, + BUTTON_UNMAXIMISE +}; + + +PanelTitlebarGrabArea::PanelTitlebarGrabArea () +: InputArea (NUX_TRACKER_LOCATION) +{ + InputArea::OnMouseDown.connect (sigc::mem_fun (this, &PanelTitlebarGrabArea::RecvMouseDown)); +} + + +PanelTitlebarGrabArea::~PanelTitlebarGrabArea () +{ +} + +const gchar * +PanelTitlebarGrabArea::GetName () +{ + return "panel-titlebar-grab-area"; +} + +const gchar * +PanelTitlebarGrabArea::GetChildsName () +{ + return ""; +} + +void +PanelTitlebarGrabArea::AddProperties (GVariantBuilder *builder) +{ + nux::Geometry geo = GetGeometry (); + + /* Now some props from ourselves */ + g_variant_builder_add (builder, "{sv}", "x", g_variant_new_int32 (geo.x)); + g_variant_builder_add (builder, "{sv}", "y", g_variant_new_int32 (geo.y)); + g_variant_builder_add (builder, "{sv}", "width", g_variant_new_int32 (geo.width)); + g_variant_builder_add (builder, "{sv}", "height", g_variant_new_int32 (geo.height)); +} + +void PanelTitlebarGrabArea::RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags) +{ + mouse_down.emit (x, y); +} + + diff --git a/src/PanelTitlebarGrabAreaView.h b/src/PanelTitlebarGrabAreaView.h new file mode 100644 index 000000000..184e5cd04 --- /dev/null +++ b/src/PanelTitlebarGrabAreaView.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2010 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com> + */ + +#ifndef PANEL_TITLEBAR_GRAB_AREA_H +#define PANEL_TITLEBAR_GRAB_AREA_H_H + +#include <Nux/View.h> + +#include "Introspectable.h" + +class PanelTitlebarGrabArea : public nux::InputArea, public Introspectable +{ + // This acts a bit like a titlebar, it can be grabbed (such that we can pull + // the window down) + +public: + PanelTitlebarGrabArea (); + ~PanelTitlebarGrabArea (); + + sigc::signal <void, int, int> mouse_down; + +protected: + const gchar * GetName (); + const gchar * GetChildsName (); + void AddProperties (GVariantBuilder *builder); + + void RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags); +}; + +#endif diff --git a/src/PanelView.cpp b/src/PanelView.cpp index f938a45a9..83bab0f99 100644 --- a/src/PanelView.cpp +++ b/src/PanelView.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -216,7 +217,7 @@ PanelView::OnObjectAdded (IndicatorObjectProxy *proxy) _layout->SetContentDistribution (nux::eStackLeft); AddChild (view); - + this->ComputeChildLayout (); NeedRedraw (); } diff --git a/src/PanelView.h b/src/PanelView.h index e96bdf41a..dff7801a6 100644 --- a/src/PanelView.h +++ b/src/PanelView.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/PluginAdapter.cpp b/src/PluginAdapter.cpp index 9d5caf14d..ef199c1e1 100644 --- a/src/PluginAdapter.cpp +++ b/src/PluginAdapter.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -17,11 +18,13 @@ */ #include <glib.h> -#include <scale/scale.h> #include "PluginAdapter.h" PluginAdapter * PluginAdapter::_default = 0; +#define MAXIMIZABLE (CompWindowActionMaximizeHorzMask & CompWindowActionMaximizeVertMask & CompWindowActionResizeMask) +#define COVERAGE_AREA_BEFORE_AUTOMAXIMIZE 0.6 + /* static */ PluginAdapter * PluginAdapter::Default () @@ -38,40 +41,55 @@ PluginAdapter::Initialize (CompScreen *screen) _default = new PluginAdapter (screen); } -PluginAdapter::PluginAdapter(CompScreen *screen) +PluginAdapter::PluginAdapter(CompScreen *screen) : + m_Screen (screen), + m_ExpoActionList (0), + m_ScaleActionList (0) { - m_Screen = screen; - m_ExpoAction = 0; - m_ScaleAction = 0; + m_AnimationPluginLoaded = + CompPlugin::find ("animation") ? true : false; } PluginAdapter::~PluginAdapter() { } -void +/* A No-op for now, but could be useful later */ +void +PluginAdapter::OnScreenGrabbed () +{ +} + +void +PluginAdapter::OnScreenUngrabbed () +{ + if (m_SpreadedWindows.size () && !screen->grabExist ("scale")) + terminate_spread.emit (m_SpreadedWindows); +} + +void PluginAdapter::NotifyResized (CompWindow *window, int x, int y, int w, int h) { - window_resized.emit (window); + window_resized.emit (window->id ()); } void PluginAdapter::NotifyMoved (CompWindow *window, int x, int y) { - window_moved.emit (window); + window_moved.emit (window->id ()); } void PluginAdapter::NotifyStateChange (CompWindow *window, unsigned int state, unsigned int last_state) { - if (!(last_state & MAXIMIZE_STATE) && (state & MAXIMIZE_STATE)) + if (!((last_state & MAXIMIZE_STATE) == MAXIMIZE_STATE) + && ((state & MAXIMIZE_STATE) == MAXIMIZE_STATE)) { - PluginAdapter::window_maximized.emit (window); WindowManager::window_maximized.emit (window->id ()); } - else if ((last_state & MAXIMIZE_STATE) && !(state & MAXIMIZE_STATE)) + else if (((last_state & MAXIMIZE_STATE) == MAXIMIZE_STATE) + && !((state & MAXIMIZE_STATE) == MAXIMIZE_STATE)) { - PluginAdapter::window_restored.emit (window); WindowManager::window_restored.emit (window->id ()); } } @@ -82,147 +100,206 @@ PluginAdapter::Notify (CompWindow *window, CompWindowNotify notify) switch (notify) { case CompWindowNotifyMinimize: - window_minimized.emit (window); + if (!m_AnimationPluginLoaded) + window_minimized.emit (window->id ()); break; case CompWindowNotifyUnminimize: - window_unminimized.emit (window); + if (!m_AnimationPluginLoaded) + window_unminimized.emit (window->id ()); break; case CompWindowNotifyShade: - window_shaded.emit (window); + window_shaded.emit (window->id ()); break; case CompWindowNotifyUnshade: - window_unshaded.emit (window); + window_unshaded.emit (window->id ()); break; case CompWindowNotifyHide: - window_hidden.emit (window); + window_hidden.emit (window->id ()); break; case CompWindowNotifyShow: - window_shown.emit (window); + window_shown.emit (window->id ()); break; case CompWindowNotifyMap: - PluginAdapter::window_mapped.emit (window); WindowManager::window_mapped.emit (window->id ()); break; case CompWindowNotifyUnmap: - PluginAdapter::window_unmapped.emit (window); WindowManager::window_unmapped.emit (window->id ()); break; + case CompWindowNotifyReparent: + MaximizeIfBigEnough (window); + break; default: break; } } void -PluginAdapter::SetExpoAction (CompAction *expo) +MultiActionList::AddNewAction (CompAction *a) { - m_ExpoAction = expo; + if (std::find (m_ActionList.begin (), m_ActionList.end (), a) == m_ActionList.end ()) + m_ActionList.push_back (a); } void -PluginAdapter::SetScaleAction (CompAction *scale) +MultiActionList::RemoveAction (CompAction *a) { - m_ScaleAction = scale; + m_ActionList.remove (a); } - -std::string * -PluginAdapter::MatchStringForXids (std::list<Window> *windows) + +bool +MultiActionList::IsAnyActive (bool onlyOwn) { - char *string; - std::string *result = new std::string ("any & ("); - - std::list<Window>::iterator it; - - for (it = windows->begin (); it != windows->end (); it++) + if (onlyOwn) + { + if (m_ToggledAction) + return true; + else + return false; + } + + foreach (CompAction *action, m_ActionList) + { + if (action->state () & (CompAction::StateTermKey | + CompAction::StateTermButton | + CompAction::StateTermEdge | + CompAction::StateTermEdgeDnd)) + return true; + } + + return m_ToggledAction ? true : false; +} + +void +MultiActionList::InitiateAll (CompOption::Vector &extraArgs) +{ + CompOption::Vector argument; + if (!m_ActionList.size ()) + return; + + argument.resize (1); + argument[0].setName ("root", CompOption::TypeInt); + argument[0].value ().set ((int) screen->root ()); + foreach (CompOption &arg, extraArgs) + { + argument.push_back (arg); + } + + /* Initiate the first available action with the arguments */ + m_ToggledAction = m_ActionList.front (); + m_ActionList.front ()->initiate () (m_ActionList.front (), 0, argument); +} + +void +MultiActionList::TerminateAll (CompOption::Vector &extraArgs) +{ + CompOption::Vector argument; + CompOption::Value value; + if (!m_ActionList.size ()) + return; + + argument.resize (1); + argument[0].setName ("root", CompOption::TypeInt); + argument[0].value ().set ((int) screen->root ()); + + foreach (CompOption &a, extraArgs) + argument.push_back (a); + + foreach (CompAction *action, m_ActionList) + { + if (action->state () & (CompAction::StateTermKey | + CompAction::StateTermButton | + CompAction::StateTermEdge | + CompAction::StateTermEdgeDnd) || + m_ToggledAction == action) { - string = g_strdup_printf ("| xid=%i ", (int) *it); - result->append (string); - g_free (string); + action->terminate () (action, 0, argument); + if (m_ToggledAction == action) + m_ToggledAction = NULL; } - - result->append (")"); - - return result; + } +} + +void +PluginAdapter::SetExpoAction (MultiActionList &expo) +{ + m_ExpoActionList = expo; +} + +void +PluginAdapter::SetScaleAction (MultiActionList &scale) +{ + m_ScaleActionList = scale; } -void -PluginAdapter::InitiateScale (std::string *match) +std::string * +PluginAdapter::MatchStringForXids (std::list<Window> *windows) { - if (!m_ScaleAction) - return; - - CompOption::Value value; - CompOption::Type type; - CompOption::Vector argument; - char *name; - - name = (char *) "root"; - type = CompOption::TypeInt; - value.set ((int) m_Screen->root ()); + char *string; + std::string *result = new std::string ("any & ("); - CompOption arg = CompOption (name, type); - arg.set (value); - argument.push_back (arg); + std::list<Window>::iterator it; - name = (char *) "match"; - type = CompOption::TypeMatch; - value.set (CompMatch (*match)); + for (it = windows->begin (); it != windows->end (); it++) + { + string = g_strdup_printf ("| xid=%i ", (int) *it); + result->append (string); + g_free (string); + } - arg = CompOption (name, type); - arg.set (value); - argument.push_back (arg); + result->append (")"); - m_ScaleAction->initiate () (m_ScaleAction, 0, argument); + return result; } -bool -PluginAdapter::IsScaleActive () +void +PluginAdapter::InitiateScale (std::string *match) { - SCALE_SCREEN(m_Screen); - return (m_ScaleAction && ss && ss->hasGrab ()); + CompOption::Vector argument; + CompMatch m (*match); + std::list <guint32> xids; + + argument.resize (1); + argument[0].setName ("match", CompOption::TypeMatch); + argument[0].value ().set (m); + + /* FIXME: Lame */ + foreach (CompWindow *w, screen->windows ()) + { + if (m.evaluate (w)) + { + if (std::find (m_SpreadedWindows.begin (), m_SpreadedWindows.end (), w->id ()) == + m_SpreadedWindows.end ()) + m_SpreadedWindows.push_back (w->id ()); + xids.push_back (w->id ()); + } + } + + initiate_spread.emit (xids); + m_ScaleActionList.InitiateAll (argument); } void PluginAdapter::TerminateScale () { - if (!IsScaleActive ()) - return; + CompOption::Vector argument (0); - CompOption::Value value; - CompOption::Type type; - CompOption::Vector argument; - char *name; + terminate_spread.emit (m_SpreadedWindows); + m_SpreadedWindows.clear (); + m_ScaleActionList.TerminateAll (argument); +} - name = (char *) "root"; - type = CompOption::TypeInt; - value.set ((int) m_Screen->root ()); - - CompOption arg = CompOption (name, type); - arg.set (value); - argument.push_back (arg); - - m_ScaleAction->terminate () (m_ScaleAction, 0, argument); +bool +PluginAdapter::IsScaleActive (bool onlyOwn) +{ + return m_ScaleActionList.IsAnyActive (onlyOwn); } void PluginAdapter::InitiateExpo () { - if (!m_ExpoAction) - return; - - CompOption::Value value; - CompOption::Type type; - CompOption::Vector argument; - char *name; - - name = (char *) "root"; - type = CompOption::TypeInt; - value.set ((int) m_Screen->root ()); - - CompOption arg (name, type); - arg.set (value); - argument.push_back (arg); + CompOption::Vector argument (0); - m_ExpoAction->initiate () (m_ExpoAction, 0, argument); + m_ExpoActionList.InitiateAll (argument); } // WindowManager implementation @@ -235,7 +312,7 @@ PluginAdapter::IsWindowMaximized (guint xid) window = m_Screen->findWindow (win); if (window) { - return window->state () & MAXIMIZE_STATE; + return ((window->state () & MAXIMIZE_STATE) == MAXIMIZE_STATE); } return false; @@ -289,3 +366,58 @@ PluginAdapter::Close (guint32 xid) if (window) window->close (CurrentTime); } + +void PluginAdapter::MaximizeIfBigEnough (CompWindow *window) +{ + XClassHint classHint; + Status status; + char* win_wmclass = NULL; + int num_monitor; + CompOutput screen; + int screen_width; + int screen_height; + float covering_part; + + if (!window) + return; + + if (window->type () != CompWindowTypeNormalMask + || (window->actions () & MAXIMIZABLE) != MAXIMIZABLE) + return; + + status = XGetClassHint (m_Screen->dpy (), window->id (), &classHint); + if (status && classHint.res_class) + { + win_wmclass = strdup (classHint.res_class); + XFree (classHint.res_class); + } + else + return; + + num_monitor = window->outputDevice(); + screen = m_Screen->outputDevs().at(num_monitor); + + screen_height = screen.workArea().height (); + screen_width = screen.workArea().width (); + + if ((window->state () & MAXIMIZE_STATE) == MAXIMIZE_STATE) { + g_debug ("MaximizeIfBigEnough: window mapped and already maximized, just undecorate"); + Undecorate (window->id ()); + return; + } + + // use server<parameter> because the window won't show the real parameter as + // not mapped yet + covering_part = (float)(window->serverWidth () * window->serverHeight ()) / (float)(screen_width * screen_height); + if ((covering_part < COVERAGE_AREA_BEFORE_AUTOMAXIMIZE) || (covering_part > 1.0)) + { + g_debug ("MaximizeIfBigEnough: %s window size doesn't fit", win_wmclass); + return; + } + + Undecorate (window->id ()); + window->maximize (MAXIMIZE_STATE); + + if (win_wmclass) + free (win_wmclass); +} diff --git a/src/PluginAdapter.h b/src/PluginAdapter.h index b1764124b..937bcf9fd 100644 --- a/src/PluginAdapter.h +++ b/src/PluginAdapter.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -26,6 +27,27 @@ #include "WindowManager.h" +class MultiActionList +{ +public: + + MultiActionList (int n) : + m_ActionList (n), + m_ToggledAction (NULL) {}; + + void InitiateAll (CompOption::Vector &extraArgs); + void TerminateAll (CompOption::Vector &extraArgs); + bool IsAnyActive (bool onlyOwn = false); + + void AddNewAction (CompAction *); + void RemoveAction (CompAction *); +private: + + std::list <CompAction *> m_ActionList; + CompAction * m_ToggledAction; +}; + + class PluginAdapter : public sigc::trackable, public WindowManager { public: @@ -37,18 +59,18 @@ public: std::string * MatchStringForXids (std::list<Window> *windows); - void SetScaleAction (CompAction *scale); - - void SetExpoAction (CompAction *expo); - - void InitiateScale (std::string *match); + void SetScaleAction (MultiActionList &scale); + void SetExpoAction (MultiActionList &expo); - bool IsScaleActive (); + void OnScreenGrabbed (); + void OnScreenUngrabbed (); + void InitiateScale (std::string *match); void TerminateScale (); + bool IsScaleActive (bool onlyOwn = false); void InitiateExpo (); - + void Notify (CompWindow *window, CompWindowNotify notify); void NotifyMoved (CompWindow *window, int x, int y); void NotifyResized (CompWindow *window, int x, int y, int w, int h); @@ -60,27 +82,18 @@ public: void Restore (guint32 xid); void Minimize (guint32 xid); void Close (guint32 xid); - - sigc::signal<void, CompWindow *> window_maximized; - sigc::signal<void, CompWindow *> window_restored; - sigc::signal<void, CompWindow *> window_minimized; - sigc::signal<void, CompWindow *> window_unminimized; - sigc::signal<void, CompWindow *> window_shaded; - sigc::signal<void, CompWindow *> window_unshaded; - sigc::signal<void, CompWindow *> window_mapped; - sigc::signal<void, CompWindow *> window_unmapped; - sigc::signal<void, CompWindow *> window_shown; - sigc::signal<void, CompWindow *> window_hidden; - sigc::signal<void, CompWindow *> window_resized; - sigc::signal<void, CompWindow *> window_moved; + + void MaximizeIfBigEnough (CompWindow *window); protected: PluginAdapter(CompScreen *screen); private: CompScreen *m_Screen; - CompAction *m_ExpoAction; - CompAction *m_ScaleAction; + MultiActionList m_ExpoActionList; + MultiActionList m_ScaleActionList; + std::list <guint32> m_SpreadedWindows; + bool m_AnimationPluginLoaded; static PluginAdapter *_default; }; diff --git a/src/QuicklistManager.cpp b/src/QuicklistManager.cpp index 940378953..6cb537809 100644 --- a/src/QuicklistManager.cpp +++ b/src/QuicklistManager.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/QuicklistManager.h b/src/QuicklistManager.h index 63a271212..ad6cb8d2c 100644 --- a/src/QuicklistManager.h +++ b/src/QuicklistManager.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/QuicklistMenuItem.cpp b/src/QuicklistMenuItem.cpp index ac1b4d615..76025352c 100644 --- a/src/QuicklistMenuItem.cpp +++ b/src/QuicklistMenuItem.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -198,10 +199,19 @@ QuicklistMenuItem::GetActive () { if (_menuItem == 0) return false; - return dbusmenu_menuitem_property_get_bool (_menuItem, + return dbusmenu_menuitem_property_get_int (_menuItem, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE) == DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED; } +bool +QuicklistMenuItem::GetVisible () +{ + if (_menuItem == 0) + return false; + return dbusmenu_menuitem_property_get_bool (_menuItem, + DBUSMENU_MENUITEM_PROP_VISIBLE); +} + void QuicklistMenuItem::ItemActivated () { if (_debug) @@ -250,7 +260,7 @@ void QuicklistMenuItem::GetTextExtents (const gchar* font, pango_layout_set_font_description (layout, desc); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); - pango_layout_set_markup (layout, _text, -1); + pango_layout_set_markup_with_accel (layout, _text, -1, '_', NULL); pangoCtx = pango_layout_get_context (layout); // is not ref'ed pango_cairo_context_set_font_options (pangoCtx, gdk_screen_get_font_options (screen)); @@ -420,7 +430,7 @@ QuicklistMenuItem::DrawText (cairo_t* cr, pango_layout_set_font_description (layout, desc); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); - pango_layout_set_markup (layout, _text, -1); + pango_layout_set_markup_with_accel (layout, _text, -1, '_', NULL); pangoCtx = pango_layout_get_context (layout); // is not ref'ed pango_cairo_context_set_font_options (pangoCtx, gdk_screen_get_font_options (screen)); @@ -465,5 +475,6 @@ void QuicklistMenuItem::AddProperties (GVariantBuilder *builder) g_variant_builder_add (builder, "{sv}", "height", g_variant_new_int32 (GetBaseHeight ())); g_variant_builder_add (builder, "{sv}", "enabled", g_variant_new_boolean (GetEnabled ())); g_variant_builder_add (builder, "{sv}", "active", g_variant_new_boolean (GetActive ())); + g_variant_builder_add (builder, "{sv}", "visible", g_variant_new_boolean (GetVisible ())); } diff --git a/src/QuicklistMenuItem.h b/src/QuicklistMenuItem.h index bf4b245a4..0a86c31ae 100644 --- a/src/QuicklistMenuItem.h +++ b/src/QuicklistMenuItem.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -87,6 +88,8 @@ class QuicklistMenuItem : public nux::View, public Introspectable virtual bool GetEnabled (); virtual bool GetActive (); + + virtual bool GetVisible (); // Introspection const gchar* GetName (); diff --git a/src/QuicklistMenuItemCheckmark.cpp b/src/QuicklistMenuItemCheckmark.cpp index 36dddf298..e46c29bda 100644 --- a/src/QuicklistMenuItemCheckmark.cpp +++ b/src/QuicklistMenuItemCheckmark.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -194,7 +195,7 @@ QuicklistMenuItemCheckmark::Draw (nux::GraphicsEngine& gfxContext, _color = nux::Color::DarkGray; } - gfxContext.QRP_GLSL_1Tex (base.x, + gfxContext.QRP_1Tex (base.x, base.y, base.width, base.height, diff --git a/src/QuicklistMenuItemCheckmark.h b/src/QuicklistMenuItemCheckmark.h index f7d46fc91..1eae205d7 100644 --- a/src/QuicklistMenuItemCheckmark.h +++ b/src/QuicklistMenuItemCheckmark.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/QuicklistMenuItemLabel.cpp b/src/QuicklistMenuItemLabel.cpp index 24504edfd..e6e101031 100644 --- a/src/QuicklistMenuItemLabel.cpp +++ b/src/QuicklistMenuItemLabel.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -165,7 +166,7 @@ QuicklistMenuItemLabel::Draw (nux::GraphicsEngine& gfxContext, _color = nux::Color::DarkGray; } - gfxContext.QRP_GLSL_1Tex (base.x, + gfxContext.QRP_1Tex (base.x, base.y, base.width, base.height, diff --git a/src/QuicklistMenuItemLabel.h b/src/QuicklistMenuItemLabel.h index 1c8936a58..d3c20e1af 100644 --- a/src/QuicklistMenuItemLabel.h +++ b/src/QuicklistMenuItemLabel.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/QuicklistMenuItemRadio.cpp b/src/QuicklistMenuItemRadio.cpp index 29b2cef25..98c03cb60 100644 --- a/src/QuicklistMenuItemRadio.cpp +++ b/src/QuicklistMenuItemRadio.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -194,7 +195,7 @@ QuicklistMenuItemRadio::Draw (nux::GraphicsEngine& gfxContext, _color = nux::Color::DarkGray; } - gfxContext.QRP_GLSL_1Tex (base.x, + gfxContext.QRP_1Tex (base.x, base.y, base.width, base.height, @@ -349,4 +350,4 @@ int QuicklistMenuItemRadio::CairoSurfaceWidth () return _normalTexture[0]->GetWidth (); return 0; -} \ No newline at end of file +} diff --git a/src/QuicklistMenuItemRadio.h b/src/QuicklistMenuItemRadio.h index 1961fdaf8..3076a4d9b 100644 --- a/src/QuicklistMenuItemRadio.h +++ b/src/QuicklistMenuItemRadio.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/QuicklistMenuItemSeparator.cpp b/src/QuicklistMenuItemSeparator.cpp index 899ccc19a..4ca8b2432 100644 --- a/src/QuicklistMenuItemSeparator.cpp +++ b/src/QuicklistMenuItemSeparator.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -122,7 +123,7 @@ QuicklistMenuItemSeparator::Draw (nux::GraphicsEngine& gfxContext, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - gfxContext.QRP_GLSL_1Tex (base.x, + gfxContext.QRP_1Tex (base.x, base.y, base.width, base.height, diff --git a/src/QuicklistMenuItemSeparator.h b/src/QuicklistMenuItemSeparator.h index 31e18d73e..6d13395e7 100644 --- a/src/QuicklistMenuItemSeparator.h +++ b/src/QuicklistMenuItemSeparator.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/QuicklistView.cpp b/src/QuicklistView.cpp index f389ab15d..cc19428ac 100644 --- a/src/QuicklistView.cpp +++ b/src/QuicklistView.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -93,6 +94,7 @@ QuicklistView::QuicklistView () _mouse_down = false; _enable_quicklist_for_testing = false; + _compute_blur_bkg = true; } QuicklistView::~QuicklistView () @@ -136,21 +138,39 @@ QuicklistView::EnableQuicklistForTesting (bool enable_testing) void QuicklistView::ShowQuicklistWithTipAt (int anchor_tip_x, int anchor_tip_y) { - int window_width; - int window_height; - - window_width = nux::GetWindow ().GetWindowWidth (); - window_height = nux::GetWindow ().GetWindowHeight (); - _anchorX = anchor_tip_x; _anchorY = anchor_tip_y; - int x = _anchorX - _padding; - int y = anchor_tip_y - _anchor_height/2 - _top_size - _corner_radius - _padding; - - SetBaseX (x); - SetBaseY (y); - + if (!_enable_quicklist_for_testing) + { + if ((_item_list.size () != 0) || (_default_item_list.size () != 0)) + { + int offscreen_size = GetBaseY () + + GetBaseHeight () - + nux::GetWindow().GetWindowHeight (); + + if (offscreen_size > 0) + _top_size = offscreen_size; + else + _top_size = 4; + + int x = _anchorX - _padding; + int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding; + + SetBaseX (x); + SetBaseY (y); + } + else + { + _top_size = 0; + int x = _anchorX - _padding; + int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding; + + SetBaseX (x); + SetBaseY (y); + } + } + Show (); } @@ -168,6 +188,8 @@ void QuicklistView::Show () EnableInputWindow (true, 1); GrabPointer (); NeedRedraw (); + + _compute_blur_bkg = true; } } @@ -239,15 +261,47 @@ long QuicklistView::ProcessEvent (nux::IEvent& ievent, long TraverseInfo, long P void QuicklistView::Draw (nux::GraphicsEngine& gfxContext, bool forceDraw) { + // Get the geometry of the QuicklistView on the display nux::Geometry base = GetGeometry(); + // Get the background of the QuicklistView and apply some + if ((nux::GetGpuDevice ()->GetGPUBrand () == nux::GPU_BRAND_NVIDIA) && _compute_blur_bkg /* Refresh the blurred background*/) + { + nux::ObjectPtr<nux::IOpenGLFrameBufferObject> current_fbo = nux::GetGpuDevice ()->GetCurrentFrameBufferObject (); + nux::GetGpuDevice ()->DeactivateFrameBuffer (); + + gfxContext.SetViewport (0, 0, gfxContext.GetWindowWidth (), gfxContext.GetWindowHeight ()); + gfxContext.SetScissor (0, 0, gfxContext.GetWindowWidth (), gfxContext.GetWindowHeight ()); + gfxContext.GetRenderStates ().EnableScissor (false); + + nux::ObjectPtr <nux::IOpenGLBaseTexture> bkg_texture = gfxContext.CreateTextureFromBackBuffer (base.x, base.y, base.width, base.height); + + nux::TexCoordXForm texxform_bkg; + bkg_blur_texture = gfxContext.QRP_GetBlurTexture (0, 0, base.width, base.height, bkg_texture, texxform_bkg, nux::Color::White, 1.0f, 3); + + if (current_fbo.IsValid ()) + { + current_fbo->Activate (true); + gfxContext.Push2DWindow (current_fbo->GetWidth (), current_fbo->GetHeight ()); + } + else + { + gfxContext.SetViewport (0, 0, gfxContext.GetWindowWidth (), gfxContext.GetWindowHeight ()); + gfxContext.Push2DWindow (gfxContext.GetWindowWidth (), gfxContext.GetWindowHeight ()); + gfxContext.ApplyClippingRectangle (); + } + _compute_blur_bkg = false; + } + // the elements position inside the window are referenced to top-left window // corner. So bring base to (0, 0). base.SetX (0); base.SetY (0); gfxContext.PushClippingRectangle (base); - nux::GetGraphicsEngine().GetRenderStates().SetBlend (false, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + nux::TexCoordXForm texxform_blur_bkg; + //texxform_blur_bkg.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP); + //texxform_blur_bkg.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD); nux::TexCoordXForm texxform_bg; texxform_bg.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP); @@ -257,8 +311,24 @@ void QuicklistView::Draw (nux::GraphicsEngine& gfxContext, bool forceDraw) texxform_mask.SetWrap(nux::TEXWRAP_CLAMP, nux::TEXWRAP_CLAMP); texxform_mask.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD); + if ((nux::GetGpuDevice ()->GetGPUBrand () == nux::GPU_BRAND_NVIDIA) && bkg_blur_texture.IsValid ()) + { + gfxContext.QRP_2TexMod ( + base.x, + base.y, + base.width, + base.height, + bkg_blur_texture, + texxform_blur_bkg, + nux::Color::White, + _texture_mask->GetDeviceTexture(), + texxform_mask, + nux::Color::White); + } - gfxContext.QRP_GLSL_2TexMod (base.x, + nux::GetGraphicsEngine().GetRenderStates().SetBlend (true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + gfxContext.QRP_2TexMod (base.x, base.y, base.width, base.height, @@ -275,7 +345,7 @@ void QuicklistView::Draw (nux::GraphicsEngine& gfxContext, bool forceDraw) texxform.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD); nux::GetGraphicsEngine().GetRenderStates().SetBlend (true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - gfxContext.QRP_GLSL_1Tex (base.x, + gfxContext.QRP_1Tex (base.x, base.y, base.width, base.height, @@ -288,12 +358,14 @@ void QuicklistView::Draw (nux::GraphicsEngine& gfxContext, bool forceDraw) std::list<QuicklistMenuItem*>::iterator it; for (it = _item_list.begin(); it != _item_list.end(); it++) { - (*it)->ProcessDraw(gfxContext, forceDraw); + if ((*it)->GetVisible()) + (*it)->ProcessDraw(gfxContext, forceDraw); } for (it = _default_item_list.begin(); it != _default_item_list.end(); it++) { - (*it)->ProcessDraw(gfxContext, forceDraw); + if ((*it)->GetVisible()) + (*it)->ProcessDraw(gfxContext, forceDraw); } gfxContext.PopClippingRectangle (); @@ -312,6 +384,14 @@ void QuicklistView::PreLayoutManagement () std::list<QuicklistMenuItem*>::iterator it; for (it = _item_list.begin(); it != _item_list.end(); it++) { + // Make sure item is in layout if it should be + if (!(*it)->GetVisible()) { + _item_layout->RemoveChildObject(*it); + continue; + } + else if (!(*it)->GetParentObject()) + _item_layout->AddView(*it, 1, nux::eCenter, nux::eFull); + int textWidth = 0; int textHeight = 0; (*it)->GetTextExtents(textWidth, textHeight); @@ -322,6 +402,14 @@ void QuicklistView::PreLayoutManagement () for (it = _default_item_list.begin(); it != _default_item_list.end(); it++) { + // Make sure item is in layout if it should be + if (!(*it)->GetVisible()) { + _default_item_layout->RemoveChildObject(*it); + continue; + } + else if (!(*it)->GetParentObject()) + _default_item_layout->AddView(*it, 1, nux::eCenter, nux::eFull); + int textWidth = 0; int textHeight = 0; (*it)->GetTextExtents(textWidth, textHeight); @@ -359,6 +447,9 @@ long QuicklistView::PostLayoutManagement (long LayoutResult) std::list<QuicklistMenuItem*>::iterator it; for (it = _item_list.begin(); it != _item_list.end(); it++) { + if (!(*it)->GetVisible()) + continue; + (*it)->SetBaseX (x); (*it)->SetBaseY (y); @@ -367,6 +458,9 @@ long QuicklistView::PostLayoutManagement (long LayoutResult) for (it = _default_item_list.begin(); it != _default_item_list.end(); it++) { + if (!(*it)->GetVisible()) + continue; + (*it)->SetBaseX (x); (*it)->SetBaseY (y); @@ -383,7 +477,7 @@ long QuicklistView::PostLayoutManagement (long LayoutResult) for (it = _item_list.begin(); it != _item_list.end(); it++) { QuicklistMenuItem* item = (QuicklistMenuItem*) (*it); - if (item->CairoSurfaceWidth () != separator_width) + if (item->GetVisible() && item->CairoSurfaceWidth () != separator_width) { // Compute textures of the item. item->UpdateTexture (); @@ -393,7 +487,7 @@ long QuicklistView::PostLayoutManagement (long LayoutResult) for (it = _default_item_list.begin(); it != _default_item_list.end(); it++) { QuicklistMenuItem* item = (QuicklistMenuItem*) (*it); - if (item->CairoSurfaceWidth () != separator_width) + if (item->GetVisible() && item->CairoSurfaceWidth () != separator_width) { // Compute textures of the item. item->UpdateTexture (); @@ -431,6 +525,9 @@ void QuicklistView::CheckAndEmitItemSignal (int x, int y) std::list<QuicklistMenuItem*>::iterator it; for (it = _item_list.begin(); it != _item_list.end(); it++) { + if (!(*it)->GetVisible()) + continue; + geo = (*it)->GetGeometry (); geo.width = _item_layout->GetBaseWidth (); @@ -446,6 +543,9 @@ void QuicklistView::CheckAndEmitItemSignal (int x, int y) for (it = _default_item_list.begin(); it != _default_item_list.end(); it++) { + if (!(*it)->GetVisible()) + continue; + geo = (*it)->GetGeometry (); geo.width = _default_item_layout->GetBaseWidth (); @@ -494,6 +594,9 @@ void QuicklistView::RecvItemMouseDrag (QuicklistMenuItem* item, int x, int y) std::list<QuicklistMenuItem*>::iterator it; for (it = _item_list.begin(); it != _item_list.end(); it++) { + if (!(*it)->GetVisible()) + continue; + geo = (*it)->GetGeometry (); geo.width = _item_layout->GetBaseWidth (); @@ -509,6 +612,9 @@ void QuicklistView::RecvItemMouseDrag (QuicklistMenuItem* item, int x, int y) for (it = _default_item_list.begin(); it != _default_item_list.end(); it++) { + if (!(*it)->GetVisible()) + continue; + geo = (*it)->GetGeometry (); geo.width = _default_item_layout->GetBaseWidth (); @@ -615,7 +721,6 @@ void QuicklistView::AddMenuItem (QuicklistMenuItem* item) item->sigMouseLeave.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseLeave)); item->sigMouseDrag.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseDrag)); - _item_layout->AddView(item, 1, nux::eCenter, nux::eFull); _item_list.push_back (item); item->Reference(); // Add to introspection @@ -1270,13 +1375,21 @@ void QuicklistView::UpdateTexture () if (_cairo_text_has_changed == false) return; - int size_above_anchor = -1; // equal to sise below + int size_above_anchor = -1; // equal to size below if (!_enable_quicklist_for_testing) { if ((_item_list.size () != 0) || (_default_item_list.size () != 0)) { - _top_size = 4; + int offscreen_size = GetBaseY () + + GetBaseHeight () - + nux::GetWindow().GetWindowHeight (); + + if (offscreen_size > 0) + _top_size = offscreen_size; + else + _top_size = 4; + size_above_anchor = _top_size; int x = _anchorX - _padding; int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding; diff --git a/src/QuicklistView.h b/src/QuicklistView.h index 26974e908..214fcf51f 100644 --- a/src/QuicklistView.h +++ b/src/QuicklistView.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -169,6 +170,8 @@ private: std::list<QuicklistMenuItem*> _item_list; std::list<QuicklistMenuItem*> _default_item_list; + bool _compute_blur_bkg; //!< If true, compute the blurred background + nux::ObjectPtr <nux::IOpenGLBaseTexture> bkg_blur_texture; // Texture holding a blurred copy of the background behind the QuicklistView // Introspection gchar *_name; diff --git a/src/SimpleLauncherIcon.cpp b/src/SimpleLauncherIcon.cpp index 732710c67..043a64ddf 100644 --- a/src/SimpleLauncherIcon.cpp +++ b/src/SimpleLauncherIcon.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -55,7 +56,7 @@ SimpleLauncherIcon::OnMouseUp (int button) void SimpleLauncherIcon::OnMouseClick (int button) { - if (button == 1) + if (button == 1 && PluginAdapter::Default ()->IsScaleActive()) PluginAdapter::Default ()->TerminateScale (); } diff --git a/src/SimpleLauncherIcon.h b/src/SimpleLauncherIcon.h index b4359e26f..73e75b019 100644 --- a/src/SimpleLauncherIcon.h +++ b/src/SimpleLauncherIcon.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -40,6 +41,7 @@ protected: virtual void OnMouseClick (int button); virtual void OnMouseEnter (); virtual void OnMouseLeave (); + private: char *m_IconName; diff --git a/src/StartupNotifyService.cpp b/src/StartupNotifyService.cpp index d915236c2..34fff34ba 100644 --- a/src/StartupNotifyService.cpp +++ b/src/StartupNotifyService.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/StartupNotifyService.h b/src/StartupNotifyService.h index 09842efa3..d2354ae8d 100644 --- a/src/StartupNotifyService.h +++ b/src/StartupNotifyService.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/StaticCairoText.cpp b/src/StaticCairoText.cpp index 178efabd9..fa09719f3 100644 --- a/src/StaticCairoText.cpp +++ b/src/StaticCairoText.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -42,20 +43,19 @@ namespace nux StaticCairoText::~StaticCairoText () { + GtkSettings* settings = gtk_settings_get_default (); // not ref'ed + g_signal_handlers_disconnect_by_func (settings, + (void *) &StaticCairoText::OnFontChanged, + this); delete (_cairoGraphics); delete (_texture2D); } void StaticCairoText::PreLayoutManagement () { - int textWidth = 0; - int textHeight = 0; - GtkSettings* settings = gtk_settings_get_default (); // not ref'ed - gchar* fontName = NULL; - - g_object_get (settings, "gtk-font-name", &fontName, NULL); - GetTextExtents (fontName, textWidth, textHeight); - g_free (fontName); + int textWidth = 0; + int textHeight = 0; + GetTextExtents (textWidth, textHeight); _pre_layout_width = GetBaseWidth (); _pre_layout_height = GetBaseHeight (); @@ -64,6 +64,12 @@ void StaticCairoText::PreLayoutManagement () if((_texture2D == 0) ) { + GtkSettings* settings = gtk_settings_get_default (); // not ref'ed + g_signal_connect (settings, "notify::gtk-font-name", + (GCallback) &StaticCairoText::OnFontChanged, this); + g_signal_connect (settings, "notify::gtk-xft-dpi", + (GCallback) &StaticCairoText::OnFontChanged, this); + UpdateTexture (); } @@ -123,7 +129,7 @@ StaticCairoText::Draw (GraphicsEngine& gfxContext, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - gfxContext.QRP_GLSL_1Tex (base.x, + gfxContext.QRP_1Tex (base.x, base.y, base.width, base.height, @@ -283,7 +289,7 @@ void StaticCairoText::DrawText (cairo_t* cr, pango_layout_context_changed (layout); - cairo_move_to (cr, 0.0f, 0.0f); + cairo_move_to (cr, -1.0f, 1.0f); pango_cairo_show_layout (cr, layout); // clean up @@ -321,4 +327,12 @@ void StaticCairoText::UpdateTexture () delete _cairoGraphics; } +void StaticCairoText::OnFontChanged (GObject *gobject, GParamSpec *pspec, + gpointer data) +{ + StaticCairoText *self = (StaticCairoText*) data; + self->UpdateTexture (); + self->sigFontChanged.emit (self); +} + } diff --git a/src/StaticCairoText.h b/src/StaticCairoText.h index 78f2f1fd7..7da23da69 100644 --- a/src/StaticCairoText.h +++ b/src/StaticCairoText.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -70,6 +71,7 @@ namespace nux sigc::signal<void, StaticCairoText*> sigTextChanged; sigc::signal<void, StaticCairoText*> sigTextColorChanged; + sigc::signal<void, StaticCairoText*> sigFontChanged; private: NString _text; @@ -90,6 +92,9 @@ namespace nux Color color); void UpdateTexture (); + + static void OnFontChanged (GObject *gobject, GParamSpec *pspec, + gpointer data); }; } diff --git a/src/Tooltip.cpp b/src/Tooltip.cpp index fdde92b16..bb1ac63d9 100644 --- a/src/Tooltip.cpp +++ b/src/Tooltip.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -67,6 +68,7 @@ namespace nux _tooltip_text = new nux::StaticCairoText (_labelText.GetTCharPtr (), NUX_TRACKER_LOCATION); _tooltip_text->sigTextChanged.connect (sigc::mem_fun (this, &Tooltip::RecvCairoTextChanged)); + _tooltip_text->sigFontChanged.connect (sigc::mem_fun (this, &Tooltip::RecvCairoTextChanged)); _tooltip_text->Reference(); _vlayout->AddView(_tooltip_text, 1, eCenter, eFull); @@ -143,7 +145,7 @@ namespace nux texxform_mask.SetTexCoordType (TexCoordXForm::OFFSET_COORD); - gfxContext.QRP_GLSL_2TexMod (base.x, + gfxContext.QRP_2TexMod (base.x, base.y, base.width, base.height, @@ -160,7 +162,7 @@ namespace nux texxform.SetTexCoordType (TexCoordXForm::OFFSET_COORD); GetGraphicsEngine().GetRenderStates().SetBlend (true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - gfxContext.QRP_GLSL_1Tex (base.x, + gfxContext.QRP_1Tex (base.x, base.y, base.width, base.height, @@ -423,15 +425,6 @@ void ctk_surface_blur (cairo_surface_t* surface, gfloat* rgba_hl, gfloat* rgba_dot) { - /*cairo_surface_t* dots_surf = NULL; - cairo_t* dots_cr = NULL; - cairo_pattern_t* dots_pattern = NULL; - cairo_pattern_t* hl_pattern = NULL;*/ - - // create context for dot-pattern - /*dots_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 4, 4); - dots_cr = cairo_create (dots_surf);*/ - // clear normal context cairo_scale (cr, 1.0f, 1.0f); cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.0f); @@ -450,52 +443,7 @@ void ctk_surface_blur (cairo_surface_t* surface, rgba_tint[1], rgba_tint[2], rgba_tint[3]); - //cairo_fill_preserve (cr); - cairo_fill (cr); - - // create pattern in dot-context - /*cairo_set_operator (dots_cr, CAIRO_OPERATOR_CLEAR); - cairo_paint (dots_cr); - cairo_scale (dots_cr, 1.0f, 1.0f); - cairo_set_operator (dots_cr, CAIRO_OPERATOR_OVER); - cairo_set_source_rgba (dots_cr, - rgba_dot[0], - rgba_dot[1], - rgba_dot[2], - rgba_dot[3]); - cairo_rectangle (dots_cr, 0.0f, 0.0f, 1.0f, 1.0f); - cairo_fill (dots_cr); - cairo_rectangle (dots_cr, 2.0f, 2.0f, 1.0f, 1.0f); - cairo_fill (dots_cr); - dots_pattern = cairo_pattern_create_for_surface (dots_surf);*/ - - // fill path of normal context with dot-pattern - /*cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - cairo_set_source (cr, dots_pattern); - cairo_pattern_set_extend (dots_pattern, CAIRO_EXTEND_REPEAT); - cairo_fill_preserve (cr); - cairo_pattern_destroy (dots_pattern); - cairo_surface_destroy (dots_surf); - cairo_destroy (dots_cr);*/ - - // draw highlight - /*cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - hl_pattern = cairo_pattern_create_radial (hl_x, - hl_y, - 0.0f, - hl_x, - hl_y, - hl_size); - cairo_pattern_add_color_stop_rgba (hl_pattern, - 0.0f, - 1.0f, - 1.0f, - 1.0f, - 0.65f); - cairo_pattern_add_color_stop_rgba (hl_pattern, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f); - cairo_set_source (cr, hl_pattern); cairo_fill (cr); - cairo_pattern_destroy (hl_pattern);*/ } void _setup (cairo_surface_t** surf, @@ -505,13 +453,6 @@ void ctk_surface_blur (cairo_surface_t* surface, gint height, gboolean negative) { -// // create context -// if (outline) -// *surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); -// else -// *surf = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height); -// *cr = cairo_create (*surf); - // clear context cairo_scale (*cr, 1.0f, 1.0f); if (outline) @@ -573,10 +514,6 @@ void ctk_surface_blur (cairo_surface_t* surface, return; } - //gint dynamic_size = height - 2*radius - 2*padding - anchor_height; - //gint upper_dynamic_size = upper_size; - //gint lower_dynamic_size = dynamic_size - upper_dynamic_size; - if(upper_size >= 0) { if(upper_size > height - 2.0f * radius - anchor_height -2 * padding) @@ -757,7 +694,6 @@ void ctk_surface_blur (cairo_surface_t* surface, _draw (cr, TRUE, line_width, rgba_shadow, FALSE, FALSE); ctk_surface_blur (surf, blur_coeff); compute_mask (cr); - //compute_outline (cr, line_width, rgba_line); } void compute_full_mask ( diff --git a/src/Tooltip.h b/src/Tooltip.h index fbbc063a3..ff9e4825e 100644 --- a/src/Tooltip.h +++ b/src/Tooltip.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * diff --git a/src/TrashLauncherIcon.cpp b/src/TrashLauncherIcon.cpp index 85ff22d01..e156dcf13 100644 --- a/src/TrashLauncherIcon.cpp +++ b/src/TrashLauncherIcon.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -25,9 +26,9 @@ TrashLauncherIcon::TrashLauncherIcon (Launcher* IconManager) { SetTooltipText ("Trash"); SetIconName ("user-trash"); - SetQuirk (LAUNCHER_ICON_QUIRK_VISIBLE, true); - SetQuirk (LAUNCHER_ICON_QUIRK_RUNNING, false); - SetIconType (LAUNCHER_ICON_TYPE_TRASH); + SetQuirk (QUIRK_VISIBLE, true); + SetQuirk (QUIRK_RUNNING, false); + SetIconType (TYPE_TRASH); m_TrashMonitor = g_file_monitor_directory (g_file_new_for_uri("trash:///"), G_FILE_MONITOR_NONE, @@ -47,6 +48,18 @@ TrashLauncherIcon::~TrashLauncherIcon() g_object_unref (m_TrashMonitor); } +nux::Color +TrashLauncherIcon::BackgroundColor () +{ + return nux::Color (0xFF333333); +} + +nux::Color +TrashLauncherIcon::GlowColor () +{ + return nux::Color (0xFF333333); +} + void TrashLauncherIcon::OnMouseClick (int button) { diff --git a/src/TrashLauncherIcon.h b/src/TrashLauncherIcon.h index c07e1a3fe..b47c85080 100644 --- a/src/TrashLauncherIcon.h +++ b/src/TrashLauncherIcon.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* * Copyright (C) 2010 Canonical Ltd * @@ -27,6 +28,9 @@ class TrashLauncherIcon : public SimpleLauncherIcon public: TrashLauncherIcon (Launcher *launcher); ~TrashLauncherIcon (); + + virtual nux::Color BackgroundColor (); + virtual nux::Color GlowColor (); protected: void OnMouseClick (int button); diff --git a/src/WindowButtons.cpp b/src/WindowButtons.cpp index 53a984f29..2d648d198 100644 --- a/src/WindowButtons.cpp +++ b/src/WindowButtons.cpp @@ -93,7 +93,7 @@ public: GL_ONE); GfxContext.GetRenderStates ().SetColorMask (true, true, true, true); if (tex) - GfxContext.QRP_GLSL_1Tex (geo.x, + GfxContext.QRP_1Tex (geo.x, geo.y, (float)geo.width, (float)geo.height, diff --git a/src/WindowManager.cpp b/src/WindowManager.cpp index 05e835f3b..224943301 100644 --- a/src/WindowManager.cpp +++ b/src/WindowManager.cpp @@ -18,8 +18,6 @@ #include "WindowManager.h" -#include <gdk/gdkx.h> - typedef struct { unsigned long flags; unsigned long functions; @@ -103,6 +101,63 @@ WindowManager::Undecorate (guint32 xid) gdk_window_set_mwm_hints (xid, &hints); } +#define NET_WM_MOVERESIZE_MOVE 8 + + +void +WindowManager::StartMove (guint32 xid, int x, int y) +{ + XEvent ev; + Display* d = nux::GetThreadGLWindow()->GetX11Display(); + + /* We first need to ungrab the pointer. FIXME: Evil */ + + XUngrabPointer(d, CurrentTime); + + // -------------------------------------------------------------------------- + // FIXME: This is a workaround until the non-paired events issue is fixed in + // nux + XButtonEvent bev = { + ButtonRelease, + 0, + False, + d, + 0, + 0, + 0, + CurrentTime, + x, y, + x, y, + 0, + Button1, + True + }; + XEvent *e = (XEvent*)&bev; + nux::GetGraphicsThread()->ProcessForeignEvent (e, NULL); + + ev.xclient.type = ClientMessage; + ev.xclient.display = d; + + ev.xclient.serial = 0; + ev.xclient.send_event = true; + + ev.xclient.window = xid; + ev.xclient.message_type = m_MoveResizeAtom; + ev.xclient.format = 32; + + ev.xclient.data.l[0] = x; + ev.xclient.data.l[1] = y; + ev.xclient.data.l[2] = NET_WM_MOVERESIZE_MOVE; + ev.xclient.data.l[3] = 1; + ev.xclient.data.l[4] = 1; + + XSendEvent (d, DefaultRootWindow (d), FALSE, + SubstructureRedirectMask | SubstructureNotifyMask, + &ev); + + XSync (d, FALSE); +} + /* * Copied over C code */ diff --git a/src/WindowManager.h b/src/WindowManager.h index 429aad2b4..3355e8b67 100644 --- a/src/WindowManager.h +++ b/src/WindowManager.h @@ -21,6 +21,10 @@ #include <glib.h> #include <sigc++/sigc++.h> +#include "Nux/Nux.h" +#include "Nux/WindowThread.h" +#include "NuxGraphics/GLWindowManager.h" +#include <gdk/gdkx.h> class WindowManager { @@ -34,6 +38,12 @@ class WindowManager // it. public: + WindowManager () : + m_MoveResizeAtom (XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), + "_NET_WM_MOVERESIZE", FALSE)) + { + } + static WindowManager * Default (); static void SetDefault (WindowManager *manager); @@ -47,11 +57,26 @@ public: virtual void Decorate (guint32 xid); virtual void Undecorate (guint32 xid); + void StartMove (guint32 id, int, int); + // Signals sigc::signal<void, guint32> window_mapped; sigc::signal<void, guint32> window_unmapped; sigc::signal<void, guint32> window_maximized; sigc::signal<void, guint32> window_restored; + sigc::signal<void, guint32> window_minimized; + sigc::signal<void, guint32> window_unminimized; + sigc::signal<void, guint32> window_shaded; + sigc::signal<void, guint32> window_unshaded; + sigc::signal<void, guint32> window_shown; + sigc::signal<void, guint32> window_hidden; + sigc::signal<void, guint32> window_resized; + sigc::signal<void, guint32> window_moved; + sigc::signal<void, std::list<guint32> &> initiate_spread; + sigc::signal<void, std::list<guint32> &> terminate_spread; + +private: + Atom m_MoveResizeAtom; }; #endif // WINDOW_MANAGER_H diff --git a/src/nux-area-accessible.cpp b/src/nux-area-accessible.cpp new file mode 100644 index 000000000..112eb73ec --- /dev/null +++ b/src/nux-area-accessible.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +/** + * SECTION:nux-area-accessible + * @Title: NuxAreaAccessible + * @short_description: Implementation of the ATK interfaces for #nux::Area + * @see_also: nux::Area + * + * #NuxAreaAccessible implements the required ATK interfaces of + * nux::Area, exposing the common elements on each basic individual + * element (position, extents, etc) + * + */ + +#include "nux-area-accessible.h" + +/* GObject */ +static void nux_area_accessible_class_init (NuxAreaAccessibleClass *klass); +static void nux_area_accessible_init (NuxAreaAccessible *area_accessible); + +/* AtkObject.h */ +static void nux_area_accessible_initialize (AtkObject *accessible, + gpointer data); + +/* AtkComponent.h */ +static void atk_component_interface_init (AtkComponentIface *iface); +static void nux_area_accessible_get_extents (AtkComponent *component, + gint *x, + gint *y, + gint *width, + gint *height, + AtkCoordType coord_type); + + + +#define NUX_AREA_ACCESSIBLE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NUX_TYPE_AREA_ACCESSIBLE, NuxAreaAccessiblePrivate)) + +G_DEFINE_TYPE_WITH_CODE (NuxAreaAccessible, nux_area_accessible, NUX_TYPE_OBJECT_ACCESSIBLE, + G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init)) + +struct _NuxAreaAccessiblePrivate +{ +}; + +static void +nux_area_accessible_class_init (NuxAreaAccessibleClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); + + /* AtkObject */ + atk_class->initialize = nux_area_accessible_initialize; + + g_type_class_add_private (gobject_class, sizeof (NuxAreaAccessiblePrivate)); +} + +static void +nux_area_accessible_init (NuxAreaAccessible *area_accessible) +{ + area_accessible->priv = NUX_AREA_ACCESSIBLE_GET_PRIVATE (area_accessible); +} + +AtkObject* +nux_area_accessible_new (nux::Object *object) +{ + AtkObject *accessible = NULL; + + g_return_val_if_fail (dynamic_cast<nux::Area*>(object), NULL); + + accessible = ATK_OBJECT (g_object_new (NUX_TYPE_AREA_ACCESSIBLE, NULL)); + + atk_object_initialize (accessible, object); + + return accessible; +} + +/* AtkObject.h */ +static void +nux_area_accessible_initialize (AtkObject *accessible, + gpointer data) +{ + ATK_OBJECT_CLASS (nux_area_accessible_parent_class)->initialize (accessible, data); + + accessible->role = ATK_ROLE_UNKNOWN; +} + +/* AtkComponent implementation */ +static void +atk_component_interface_init (AtkComponentIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->get_extents = nux_area_accessible_get_extents; + + /* FIXME: focus management missing */ +} + +static void +nux_area_accessible_get_extents (AtkComponent *component, + gint *x, + gint *y, + gint *width, + gint *height, + AtkCoordType coord_type) +{ + gint top_level_x = 0; + gint top_level_y = 0; + nux::Object *nux_object = NULL; + nux::Area *area = NULL; + nux::Geometry geometry; + + g_return_if_fail (NUX_IS_AREA_ACCESSIBLE (component)); + + nux_object = nux_object_accessible_get_object (NUX_OBJECT_ACCESSIBLE (component)); + + if (nux_object == NULL) /* actor is defunct */ + return; + + area = dynamic_cast<nux::Area *>(nux_object); + + geometry = area->GetGeometry (); + + *width = geometry.GetWidth (); + *height = geometry.GetWidth (); + *x = geometry.x; + *y = geometry.y; + + /* In the ATK_XY_WINDOW case + * + * http://library.gnome.org/devel/atk/stable/AtkUtil.html#AtkCoordType + */ + + if (coord_type == ATK_XY_SCREEN) + { + /* For the moment Unity is a full-screen app, so ATK_XY_SCREEN + and ATK_XY_WINDOW are the same */ + *x += top_level_x; + *y += top_level_y; + } + + return; +} diff --git a/src/nux-area-accessible.h b/src/nux-area-accessible.h new file mode 100644 index 000000000..076d7da9b --- /dev/null +++ b/src/nux-area-accessible.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +#ifndef NUX_AREA_ACCESSIBLE_H +#define NUX_AREA_ACCESSIBLE_H + +#include <atk/atk.h> + +#include "nux-object-accessible.h" + +G_BEGIN_DECLS + +#define NUX_TYPE_AREA_ACCESSIBLE (nux_area_accessible_get_type ()) +#define NUX_AREA_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NUX_TYPE_AREA_ACCESSIBLE, NuxAreaAccessible)) +#define NUX_AREA_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NUX_TYPE_AREA_ACCESSIBLE, NuxAreaAccessibleClass)) +#define NUX_IS_AREA_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NUX_TYPE_AREA_ACCESSIBLE)) +#define NUX_IS_AREA_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NUX_TYPE_AREA_ACCESSIBLE)) +#define NUX_AREA_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NUX_TYPE_AREA_ACCESSIBLE, NuxAreaAccessibleClass)) + +typedef struct _NuxAreaAccessible NuxAreaAccessible; +typedef struct _NuxAreaAccessibleClass NuxAreaAccessibleClass; +typedef struct _NuxAreaAccessiblePrivate NuxAreaAccessiblePrivate; + +struct _NuxAreaAccessible +{ + NuxObjectAccessible parent; + + /* < private > */ + NuxAreaAccessiblePrivate *priv; +}; + +struct _NuxAreaAccessibleClass +{ + NuxObjectAccessibleClass parent_class; +}; + +GType nux_area_accessible_get_type (void); +AtkObject *nux_area_accessible_new (nux::Object *object); + +G_END_DECLS + +#endif /* __NUX_AREA_ACCESSIBLE_H__ */ diff --git a/src/nux-base-window-accessible.cpp b/src/nux-base-window-accessible.cpp new file mode 100644 index 000000000..ffb37eaf6 --- /dev/null +++ b/src/nux-base-window-accessible.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +/** + * SECTION:nux-base_window-accessible + * @Title: NuxBaseWindowAccessible + * @short_description: Implementation of the ATK interfaces for #nux::BaseWindow + * @see_also: nux::BaseWindow + * + * Right now it is only here to expose the child of BaseWindow (the layout) + * + * #NuxBaseWindowAccessible implements the required ATK interfaces of + * nux::BaseWindow, exposing as a child the BaseWindow layout + * + */ + +#include "nux-base-window-accessible.h" +#include "unitya11y.h" + +#include "Nux/Area.h" +#include "Nux/Layout.h" + +/* GObject */ +static void nux_base_window_accessible_class_init (NuxBaseWindowAccessibleClass *klass); +static void nux_base_window_accessible_init (NuxBaseWindowAccessible *base_window_accessible); + +/* AtkObject.h */ +static void nux_base_window_accessible_initialize (AtkObject *accessible, + gpointer data); +static gint nux_base_window_accessible_get_n_children (AtkObject *obj); +static AtkObject *nux_base_window_accessible_ref_child (AtkObject *obj, + gint i); +static AtkObject *nux_base_window_accessible_get_parent (AtkObject *obj); + + +#define NUX_BASE_WINDOW_ACCESSIBLE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NUX_TYPE_BASE_WINDOW_ACCESSIBLE, NuxBaseWindowAccessiblePrivate)) + +G_DEFINE_TYPE (NuxBaseWindowAccessible, nux_base_window_accessible, NUX_TYPE_VIEW_ACCESSIBLE) + +struct _NuxBaseWindowAccessiblePrivate +{ + +}; + +static void +nux_base_window_accessible_class_init (NuxBaseWindowAccessibleClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); + + /* AtkObject */ + atk_class->initialize = nux_base_window_accessible_initialize; + atk_class->get_n_children = nux_base_window_accessible_get_n_children; + atk_class->ref_child = nux_base_window_accessible_ref_child; + atk_class->get_parent = nux_base_window_accessible_get_parent; + + g_type_class_add_private (gobject_class, sizeof (NuxBaseWindowAccessiblePrivate)); +} + +static void +nux_base_window_accessible_init (NuxBaseWindowAccessible *base_window_accessible) +{ + base_window_accessible->priv = NUX_BASE_WINDOW_ACCESSIBLE_GET_PRIVATE (base_window_accessible); +} + +AtkObject* +nux_base_window_accessible_new (nux::Object *object) +{ + AtkObject *accessible = NULL; + + g_return_val_if_fail (dynamic_cast<nux::BaseWindow*>(object), NULL); + + accessible = ATK_OBJECT (g_object_new (NUX_TYPE_BASE_WINDOW_ACCESSIBLE, NULL)); + + atk_object_initialize (accessible, object); + + return accessible; +} + +/* AtkObject.h */ +static void +nux_base_window_accessible_initialize (AtkObject *accessible, + gpointer data) +{ + ATK_OBJECT_CLASS (nux_base_window_accessible_parent_class)->initialize (accessible, data); + + accessible->role = ATK_ROLE_WINDOW; +} + +static gint +nux_base_window_accessible_get_n_children (AtkObject *obj) +{ + nux::Object *nux_object = NULL; + nux::BaseWindow *base_window = NULL; + nux::Layout *layout = NULL; + + g_return_val_if_fail (NUX_IS_BASE_WINDOW_ACCESSIBLE (obj), 0); + + nux_object = nux_object_accessible_get_object (NUX_OBJECT_ACCESSIBLE (obj)); + if (nux_object == NULL) /* state is defunct */ + return 0; + base_window = dynamic_cast<nux::BaseWindow *>(nux_object); + + layout = base_window->GetLayout (); + + if (layout == NULL) + return 0; + else + return 1; +} + +static AtkObject * +nux_base_window_accessible_ref_child (AtkObject *obj, + gint i) +{ + nux::Object *nux_object = NULL; + nux::BaseWindow *base_window = NULL; + nux::Layout *layout = NULL; + AtkObject *layout_accessible = NULL; + gint num = 0; + + g_return_val_if_fail (NUX_IS_BASE_WINDOW_ACCESSIBLE (obj), 0); + num = atk_object_get_n_accessible_children (obj); + g_return_val_if_fail ((i < num)&&(i >= 0), NULL); + + nux_object = nux_object_accessible_get_object (NUX_OBJECT_ACCESSIBLE (obj)); + if (nux_object == NULL) /* state is defunct */ + return 0; + + base_window = dynamic_cast<nux::BaseWindow *>(nux_object); + + layout = base_window->GetLayout (); + + layout_accessible = unity_a11y_get_accessible (layout); + + g_object_ref (layout_accessible); + + return layout_accessible; +} + +static AtkObject +*nux_base_window_accessible_get_parent (AtkObject *obj) +{ + return NULL; +} diff --git a/src/nux-base-window-accessible.h b/src/nux-base-window-accessible.h new file mode 100644 index 000000000..e52cba12a --- /dev/null +++ b/src/nux-base-window-accessible.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +#ifndef NUX_BASE_WINDOW_ACCESSIBLE_H +#define NUX_BASE_WINDOW_ACCESSIBLE_H + +#include <atk/atk.h> + +#include "Nux/Nux.h" +#include "Nux/BaseWindow.h" + +#include "nux-view-accessible.h" + +G_BEGIN_DECLS + +#define NUX_TYPE_BASE_WINDOW_ACCESSIBLE (nux_base_window_accessible_get_type ()) +#define NUX_BASE_WINDOW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NUX_TYPE_BASE_WINDOW_ACCESSIBLE, NuxBaseWindowAccessible)) +#define NUX_BASE_WINDOW_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NUX_TYPE_BASE_WINDOW_ACCESSIBLE, NuxBaseWindowAccessibleClass)) +#define NUX_IS_BASE_WINDOW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NUX_TYPE_BASE_WINDOW_ACCESSIBLE)) +#define NUX_IS_BASE_WINDOW_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NUX_TYPE_BASE_WINDOW_ACCESSIBLE)) +#define NUX_BASE_WINDOW_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NUX_TYPE_BASE_WINDOW_ACCESSIBLE, NuxBaseWindowAccessibleClass)) + +typedef struct _NuxBaseWindowAccessible NuxBaseWindowAccessible; +typedef struct _NuxBaseWindowAccessibleClass NuxBaseWindowAccessibleClass; +typedef struct _NuxBaseWindowAccessiblePrivate NuxBaseWindowAccessiblePrivate; + +struct _NuxBaseWindowAccessible +{ + NuxViewAccessible parent; + + /* < private > */ + NuxBaseWindowAccessiblePrivate *priv; +}; + +struct _NuxBaseWindowAccessibleClass +{ + NuxViewAccessibleClass parent_class; +}; + +GType nux_base_window_accessible_get_type (void); +AtkObject *nux_base_window_accessible_new (nux::Object *object); + +G_END_DECLS + +#endif /* __NUX_BASE_WINDOW_ACCESSIBLE_H__ */ diff --git a/src/nux-layout-accessible.cpp b/src/nux-layout-accessible.cpp new file mode 100644 index 000000000..841b2b43d --- /dev/null +++ b/src/nux-layout-accessible.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +/** + * SECTION:nux-layout-accessible + * @Title: NuxLayoutAccessible + * @short_description: Implementation of the ATK interfaces for #nux::Layout + * @see_also: nux::Layout + * + * #NuxLayoutAccessible implements the required ATK interfaces of + * nux::Layout, implementing the container related methods on + * AtkObject, in order to expose his objects + * + */ + +#include "nux-layout-accessible.h" + +#include "unitya11y.h" + +/* GObject */ +static void nux_layout_accessible_class_init (NuxLayoutAccessibleClass *klass); +static void nux_layout_accessible_init (NuxLayoutAccessible *layout_accessible); + +/* AtkObject.h */ +static void nux_layout_accessible_initialize (AtkObject *accessible, + gpointer data); +static gint nux_layout_accessible_get_n_children (AtkObject *obj); +static AtkObject *nux_layout_accessible_ref_child (AtkObject *obj, + gint i); + + +#define NUX_LAYOUT_ACCESSIBLE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NUX_TYPE_LAYOUT_ACCESSIBLE, NuxLayoutAccessiblePrivate)) + +G_DEFINE_TYPE (NuxLayoutAccessible, nux_layout_accessible, NUX_TYPE_AREA_ACCESSIBLE) + +struct _NuxLayoutAccessiblePrivate +{ +}; + +static void +nux_layout_accessible_class_init (NuxLayoutAccessibleClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); + + /* AtkObject */ + atk_class->initialize = nux_layout_accessible_initialize; + atk_class->ref_child = nux_layout_accessible_ref_child; + atk_class->get_n_children = nux_layout_accessible_get_n_children; + + g_type_class_add_private (gobject_class, sizeof (NuxLayoutAccessiblePrivate)); +} + +static void +nux_layout_accessible_init (NuxLayoutAccessible *layout_accessible) +{ + layout_accessible->priv = NUX_LAYOUT_ACCESSIBLE_GET_PRIVATE (layout_accessible); +} + +AtkObject* +nux_layout_accessible_new (nux::Object *object) +{ + AtkObject *accessible = NULL; + + g_return_val_if_fail (dynamic_cast<nux::Layout *>(object), NULL); + + accessible = ATK_OBJECT (g_object_new (NUX_TYPE_LAYOUT_ACCESSIBLE, NULL)); + + atk_object_initialize (accessible, object); + + return accessible; +} + +/* AtkObject.h */ +static void +nux_layout_accessible_initialize (AtkObject *accessible, + gpointer data) +{ + ATK_OBJECT_CLASS (nux_layout_accessible_parent_class)->initialize (accessible, data); + + accessible->role = ATK_ROLE_PANEL; +} + +static gint +nux_layout_accessible_get_n_children (AtkObject *obj) +{ + nux::Object *nux_object = NULL; + nux::Layout *layout = NULL; + std::list<nux::Area *> element_list; + + g_return_val_if_fail (NUX_IS_LAYOUT_ACCESSIBLE (obj), 0); + + nux_object = nux_object_accessible_get_object (NUX_OBJECT_ACCESSIBLE (obj)); + if (!nux_object) /* state is defunct */ + return 0; + + layout = dynamic_cast<nux::Layout *>(nux_object); + + element_list = layout->GetChildren (); + + return element_list.size (); +} + +static AtkObject * +nux_layout_accessible_ref_child (AtkObject *obj, + gint i) +{ + nux::Object *nux_object = NULL; + nux::Object *child = NULL; + AtkObject *child_accessible = NULL; + nux::Layout *layout = NULL; + std::list<nux::Area *> element_list; + gint num = 0; + std::list<nux::Area *>::iterator it; + + g_return_val_if_fail (NUX_IS_LAYOUT_ACCESSIBLE (obj), 0); + num = atk_object_get_n_accessible_children (obj); + g_return_val_if_fail ((i < num)&&(i >= 0), NULL); + + nux_object = nux_object_accessible_get_object (NUX_OBJECT_ACCESSIBLE (obj)); + if (!nux_object) /* state is defunct */ + return 0; + + layout = dynamic_cast<nux::Layout *>(nux_object); + + element_list = layout->GetChildren (); + + it = element_list.begin (); + std::advance (it, i); + + child = dynamic_cast<nux::Object *>(*it); + child_accessible = unity_a11y_get_accessible (child); + + g_object_ref (child_accessible); + + return child_accessible; +} diff --git a/src/nux-layout-accessible.h b/src/nux-layout-accessible.h new file mode 100644 index 000000000..be67d51eb --- /dev/null +++ b/src/nux-layout-accessible.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +#ifndef NUX_LAYOUT_ACCESSIBLE_H +#define NUX_LAYOUT_ACCESSIBLE_H + +#include <atk/atk.h> + +#include "nux-area-accessible.h" + +#include "Nux/Nux.h" +#include "Nux/Layout.h" + +G_BEGIN_DECLS + +#define NUX_TYPE_LAYOUT_ACCESSIBLE (nux_layout_accessible_get_type ()) +#define NUX_LAYOUT_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NUX_TYPE_LAYOUT_ACCESSIBLE, NuxLayoutAccessible)) +#define NUX_LAYOUT_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NUX_TYPE_LAYOUT_ACCESSIBLE, NuxLayoutAccessibleClass)) +#define NUX_IS_LAYOUT_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NUX_TYPE_LAYOUT_ACCESSIBLE)) +#define NUX_IS_LAYOUT_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NUX_TYPE_LAYOUT_ACCESSIBLE)) +#define NUX_LAYOUT_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NUX_TYPE_LAYOUT_ACCESSIBLE, NuxLayoutAccessibleClass)) + +typedef struct _NuxLayoutAccessible NuxLayoutAccessible; +typedef struct _NuxLayoutAccessibleClass NuxLayoutAccessibleClass; +typedef struct _NuxLayoutAccessiblePrivate NuxLayoutAccessiblePrivate; + +struct _NuxLayoutAccessible +{ + NuxAreaAccessible parent; + + /* < private > */ + NuxLayoutAccessiblePrivate *priv; +}; + +struct _NuxLayoutAccessibleClass +{ + NuxAreaAccessibleClass parent_class; +}; + +GType nux_layout_accessible_get_type (void); +AtkObject *nux_layout_accessible_new (nux::Object *object); + +G_END_DECLS + +#endif /* __NUX_LAYOUT_ACCESSIBLE_H__ */ diff --git a/src/nux-object-accessible.cpp b/src/nux-object-accessible.cpp new file mode 100644 index 000000000..000aa2acd --- /dev/null +++ b/src/nux-object-accessible.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +/** + * SECTION:nux-object-accessible + * @Title: NuxObjectAccessible + * @short_description: Implementation of the ATK interfaces for #nux::Object + * @see_also: nux::Object + * + * #NuxObjectAccessible implements the required ATK interfaces of + * nux::Object, exposing the common elements on each basic individual + * element (position, extents, etc) + * + */ + +#include "nux-object-accessible.h" + +/* GObject */ +static void nux_object_accessible_class_init (NuxObjectAccessibleClass *klass); +static void nux_object_accessible_init (NuxObjectAccessible *object_accessible); + +/* AtkObject.h */ +static void nux_object_accessible_initialize (AtkObject *accessible, + gpointer data); + +#define NUX_OBJECT_ACCESSIBLE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NUX_TYPE_OBJECT_ACCESSIBLE, NuxObjectAccessiblePrivate)) + +G_DEFINE_TYPE (NuxObjectAccessible, nux_object_accessible, ATK_TYPE_OBJECT) + +struct _NuxObjectAccessiblePrivate +{ + nux::Object *object; +}; + +static void +nux_object_accessible_class_init (NuxObjectAccessibleClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); + + /* AtkObject */ + atk_class->initialize = nux_object_accessible_initialize; + + g_type_class_add_private (gobject_class, sizeof (NuxObjectAccessiblePrivate)); +} + +static void +nux_object_accessible_init (NuxObjectAccessible *object_accessible) +{ + object_accessible->priv = NUX_OBJECT_ACCESSIBLE_GET_PRIVATE (object_accessible); + + object_accessible->priv->object = NULL; +} + +AtkObject* +nux_object_accessible_new (nux::Object *object) +{ + AtkObject *accessible = NULL; + + g_return_val_if_fail (dynamic_cast<nux::Object *>(object), NULL); + + accessible = ATK_OBJECT (g_object_new (NUX_TYPE_OBJECT_ACCESSIBLE, NULL)); + + atk_object_initialize (accessible, object); + + return accessible; +} + +/* AtkObject.h */ +static void +nux_object_accessible_initialize (AtkObject *accessible, + gpointer data) +{ + NuxObjectAccessible *self = NULL; + nux::Object *object = NULL; + + ATK_OBJECT_CLASS (nux_object_accessible_parent_class)->initialize (accessible, data); + + /* FIXME: focus management missing */ + self = NUX_OBJECT_ACCESSIBLE (accessible); + object = (nux::Object*)data; + + self->priv->object = object; /* FIXME: object destruction management (for + the defunct state) */ + accessible->role = ATK_ROLE_UNKNOWN; +} + +/** + * nux_object_accessible_get_object: + * + * Returns the nux::Object this object is providing accessibility support. + * + * Note that there isn't a _set method. This is because setting that + * should only be done during initilization, and it doesn't make sense + * to change that during the life of the object. + * + */ +nux::Object * +nux_object_accessible_get_object (NuxObjectAccessible *self) +{ + return self->priv->object; +} diff --git a/src/nux-object-accessible.h b/src/nux-object-accessible.h new file mode 100644 index 000000000..2c3615217 --- /dev/null +++ b/src/nux-object-accessible.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +#ifndef NUX_OBJECT_ACCESSIBLE_H +#define NUX_OBJECT_ACCESSIBLE_H + +#include <atk/atk.h> + +#include "Nux/Nux.h" +#include "NuxCore/Object.h" + +G_BEGIN_DECLS + +#define NUX_TYPE_OBJECT_ACCESSIBLE (nux_object_accessible_get_type ()) +#define NUX_OBJECT_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NUX_TYPE_OBJECT_ACCESSIBLE, NuxObjectAccessible)) +#define NUX_OBJECT_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NUX_TYPE_OBJECT_ACCESSIBLE, NuxObjectAccessibleClass)) +#define NUX_IS_OBJECT_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NUX_TYPE_OBJECT_ACCESSIBLE)) +#define NUX_IS_OBJECT_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NUX_TYPE_OBJECT_ACCESSIBLE)) +#define NUX_OBJECT_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NUX_TYPE_OBJECT_ACCESSIBLE, NuxObjectAccessibleClass)) + +typedef struct _NuxObjectAccessible NuxObjectAccessible; +typedef struct _NuxObjectAccessibleClass NuxObjectAccessibleClass; +typedef struct _NuxObjectAccessiblePrivate NuxObjectAccessiblePrivate; + +struct _NuxObjectAccessible +{ + AtkObject parent; + + /* < private > */ + NuxObjectAccessiblePrivate *priv; +}; + +struct _NuxObjectAccessibleClass +{ + AtkObjectClass parent_class; +}; + +GType nux_object_accessible_get_type (void); +AtkObject *nux_object_accessible_new (nux::Object *object); + +nux::Object *nux_object_accessible_get_object (NuxObjectAccessible *self); + +G_END_DECLS + +#endif /* __NUX_OBJECT_ACCESSIBLE_H__ */ diff --git a/src/nux-view-accessible.cpp b/src/nux-view-accessible.cpp new file mode 100644 index 000000000..34462ce3b --- /dev/null +++ b/src/nux-view-accessible.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +/** + * SECTION:nux-view-accessible + * @Title: NuxViewAccessible + * @short_description: Implementation of the ATK interfaces for #nux::View + * @see_also: nux::View + * + * #NuxViewAccessible implements the required ATK interfaces of + * nux::View + * + */ + +#include "nux-view-accessible.h" + +/* GObject */ +static void nux_view_accessible_class_init (NuxViewAccessibleClass *klass); +static void nux_view_accessible_init (NuxViewAccessible *view_accessible); + +/* AtkObject.h */ +static void nux_view_accessible_initialize (AtkObject *accessible, + gpointer data); + +#define NUX_VIEW_ACCESSIBLE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NUX_TYPE_VIEW_ACCESSIBLE, NuxViewAccessiblePrivate)) + +G_DEFINE_TYPE (NuxViewAccessible, nux_view_accessible, NUX_TYPE_AREA_ACCESSIBLE) + +struct _NuxViewAccessiblePrivate +{ +}; + +static void +nux_view_accessible_class_init (NuxViewAccessibleClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); + + /* AtkObject */ + atk_class->initialize = nux_view_accessible_initialize; + + g_type_class_add_private (gobject_class, sizeof (NuxViewAccessiblePrivate)); +} + +static void +nux_view_accessible_init (NuxViewAccessible *view_accessible) +{ + view_accessible->priv = NUX_VIEW_ACCESSIBLE_GET_PRIVATE (view_accessible); +} + +AtkObject* +nux_view_accessible_new (nux::Object *object) +{ + AtkObject *accessible = NULL; + + g_return_val_if_fail (dynamic_cast<nux::View *>(object), NULL); + + accessible = ATK_OBJECT (g_object_new (NUX_TYPE_VIEW_ACCESSIBLE, NULL)); + + atk_object_initialize (accessible, object); + + return accessible; +} + +/* AtkObject.h */ +static void +nux_view_accessible_initialize (AtkObject *accessible, + gpointer data) +{ + ATK_OBJECT_CLASS (nux_view_accessible_parent_class)->initialize (accessible, data); + + accessible->role = ATK_ROLE_UNKNOWN; +} diff --git a/src/nux-view-accessible.h b/src/nux-view-accessible.h new file mode 100644 index 000000000..ba127b4cd --- /dev/null +++ b/src/nux-view-accessible.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +#ifndef NUX_VIEW_ACCESSIBLE_H +#define NUX_VIEW_ACCESSIBLE_H + +#include <atk/atk.h> + +#include "nux-area-accessible.h" + +#include "Nux/Nux.h" +#include "Nux/View.h" + +G_BEGIN_DECLS + +#define NUX_TYPE_VIEW_ACCESSIBLE (nux_view_accessible_get_type ()) +#define NUX_VIEW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NUX_TYPE_VIEW_ACCESSIBLE, NuxViewAccessible)) +#define NUX_VIEW_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NUX_TYPE_VIEW_ACCESSIBLE, NuxViewAccessibleClass)) +#define NUX_IS_VIEW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NUX_TYPE_VIEW_ACCESSIBLE)) +#define NUX_IS_VIEW_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NUX_TYPE_VIEW_ACCESSIBLE)) +#define NUX_VIEW_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NUX_TYPE_VIEW_ACCESSIBLE, NuxViewAccessibleClass)) + +typedef struct _NuxViewAccessible NuxViewAccessible; +typedef struct _NuxViewAccessibleClass NuxViewAccessibleClass; +typedef struct _NuxViewAccessiblePrivate NuxViewAccessiblePrivate; + +struct _NuxViewAccessible +{ + NuxAreaAccessible parent; + + /* < private > */ + NuxViewAccessiblePrivate *priv; +}; + +struct _NuxViewAccessibleClass +{ + NuxAreaAccessibleClass parent_class; +}; + +GType nux_view_accessible_get_type (void); +AtkObject *nux_view_accessible_new (nux::Object *object); + +G_END_DECLS + +#endif /* __NUX_VIEW_ACCESSIBLE_H__ */ diff --git a/src/unity-launcher-accessible.cpp b/src/unity-launcher-accessible.cpp new file mode 100644 index 000000000..686c1a0de --- /dev/null +++ b/src/unity-launcher-accessible.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +/** + * SECTION:nux-view-accessible + * @Title: NuxViewAccessible + * @short_description: Implementation of the ATK interfaces for #Launcher + * @see_also: Launcher + * + * #NuxViewAccessible implements the required ATK interfaces for + * #Launcher, ie: exposing the different LauncherIcon on the model as + * #child of the object. + * + */ + +#include "unity-launcher-accessible.h" + +#include "unitya11y.h" +#include "Launcher.h" +#include "LauncherModel.h" + +/* GObject */ +static void unity_launcher_accessible_class_init (UnityLauncherAccessibleClass *klass); +static void unity_launcher_accessible_init (UnityLauncherAccessible *self); + +/* AtkObject.h */ +static void unity_launcher_accessible_initialize (AtkObject *accessible, + gpointer data); +static gint unity_launcher_accessible_get_n_children (AtkObject *obj); +static AtkObject *unity_launcher_accessible_ref_child (AtkObject *obj, + gint i); + +#define UNITY_LAUNCHER_ACCESSIBLE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), UNITY_TYPE_LAUNCHER_ACCESSIBLE, UnityLauncherAccessiblePrivate)) + +G_DEFINE_TYPE (UnityLauncherAccessible, unity_launcher_accessible, NUX_TYPE_VIEW_ACCESSIBLE) + +struct _UnityLauncherAccessiblePrivate +{ +}; + +static void +unity_launcher_accessible_class_init (UnityLauncherAccessibleClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); + + /* AtkObject */ + atk_class->get_n_children = unity_launcher_accessible_get_n_children; + atk_class->ref_child = unity_launcher_accessible_ref_child; + atk_class->initialize = unity_launcher_accessible_initialize; + + g_type_class_add_private (gobject_class, sizeof (UnityLauncherAccessiblePrivate)); +} + +static void +unity_launcher_accessible_init (UnityLauncherAccessible *self) +{ + self->priv = UNITY_LAUNCHER_ACCESSIBLE_GET_PRIVATE (self); +} + +AtkObject* +unity_launcher_accessible_new (nux::Object *object) +{ + AtkObject *accessible = NULL; + + g_return_val_if_fail (dynamic_cast<Launcher *>(object), NULL); + + accessible = ATK_OBJECT (g_object_new (UNITY_TYPE_LAUNCHER_ACCESSIBLE, NULL)); + + atk_object_initialize (accessible, object); + + return accessible; +} + +/* AtkObject.h */ +static void +unity_launcher_accessible_initialize (AtkObject *accessible, + gpointer data) +{ + ATK_OBJECT_CLASS (unity_launcher_accessible_parent_class)->initialize (accessible, data); + + accessible->role = ATK_ROLE_TOOL_BAR; +} + +static gint +unity_launcher_accessible_get_n_children (AtkObject *obj) +{ + nux::Object *object = NULL; + Launcher *launcher = NULL; + LauncherModel *launcher_model = NULL; + + g_return_val_if_fail (UNITY_IS_LAUNCHER_ACCESSIBLE (obj), 0); + + object = nux_object_accessible_get_object (NUX_OBJECT_ACCESSIBLE (obj)); + if (!object) /* state is defunct */ + return 0; + + launcher = dynamic_cast<Launcher *>(object); + + launcher_model = launcher->GetModel (); + + if (launcher_model) + return launcher_model->Size (); + else + return 0; +} + +static AtkObject* +unity_launcher_accessible_ref_child (AtkObject *obj, + gint i) +{ + gint num = 0; + nux::Object *nux_object = NULL; + Launcher *launcher = NULL; + LauncherModel *launcher_model = NULL; + LauncherModel::iterator it; + nux::Object *child = NULL; + AtkObject *child_accessible = NULL; + + num = atk_object_get_n_accessible_children (obj); + g_return_val_if_fail ((i < num)&&(i >= 0), NULL); + + nux_object = nux_object_accessible_get_object (NUX_OBJECT_ACCESSIBLE (obj)); + if (!nux_object) /* state is defunct */ + return 0; + + launcher = dynamic_cast<Launcher *>(nux_object); + launcher_model = launcher->GetModel (); + + it = launcher_model->begin (); + std::advance (it, i); + + child = dynamic_cast<nux::Object *>(*it); + child_accessible = unity_a11y_get_accessible (child); + + g_object_ref (child_accessible); + + return child_accessible; +} diff --git a/src/unity-launcher-accessible.h b/src/unity-launcher-accessible.h new file mode 100644 index 000000000..2039cfce7 --- /dev/null +++ b/src/unity-launcher-accessible.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +#ifndef UNITY_LAUNCHER_ACCESSIBLE_H +#define UNITY_LAUNCHER_ACCESSIBLE_H + +#include <atk/atk.h> + +#include "nux-view-accessible.h" + +G_BEGIN_DECLS + +#define UNITY_TYPE_LAUNCHER_ACCESSIBLE (unity_launcher_accessible_get_type ()) +#define UNITY_LAUNCHER_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_TYPE_LAUNCHER_ACCESSIBLE, UnityLauncherAccessible)) +#define UNITY_LAUNCHER_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_TYPE_LAUNCHER_ACCESSIBLE, UnityLauncherAccessibleClass)) +#define UNITY_IS_LAUNCHER_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_TYPE_LAUNCHER_ACCESSIBLE)) +#define UNITY_IS_LAUNCHER_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_TYPE_LAUNCHER_ACCESSIBLE)) +#define UNITY_LAUNCHER_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_TYPE_LAUNCHER_ACCESSIBLE, UnityLauncherAccessibleClass)) + +typedef struct _UnityLauncherAccessible UnityLauncherAccessible; +typedef struct _UnityLauncherAccessibleClass UnityLauncherAccessibleClass; +typedef struct _UnityLauncherAccessiblePrivate UnityLauncherAccessiblePrivate; + +struct _UnityLauncherAccessible +{ + NuxViewAccessible parent; + + /* < private > */ + UnityLauncherAccessiblePrivate *priv; +}; + +struct _UnityLauncherAccessibleClass +{ + NuxViewAccessibleClass parent_class; +}; + +GType unity_launcher_accessible_get_type (void); +AtkObject *unity_launcher_accessible_new (nux::Object *object); + +G_END_DECLS + +#endif /* __UNITY_LAUNCHER_ACCESSIBLE_H__ */ diff --git a/src/unity-launcher-icon-accessible.cpp b/src/unity-launcher-icon-accessible.cpp new file mode 100644 index 000000000..bde5c8815 --- /dev/null +++ b/src/unity-launcher-icon-accessible.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +/** + * SECTION:nux-launcher_icon-accessible + * @Title: UnityLauncherIconAccessible + * @short_description: Implementation of the ATK interfaces for #nux::LauncherIcon + * @see_also: nux::LauncherIcon + * + * #UnityLauncherIconAccessible implements the required ATK interfaces of + * nux::LauncherIcon, exposing the common elements on each basic individual + * element (position, extents, etc) + * + */ + +#include "unity-launcher-icon-accessible.h" +#include "LauncherIcon.h" + +/* GObject */ +static void unity_launcher_icon_accessible_class_init (UnityLauncherIconAccessibleClass *klass); +static void unity_launcher_icon_accessible_init (UnityLauncherIconAccessible *launcher_icon_accessible); + +/* AtkObject.h */ +static void unity_launcher_icon_accessible_initialize (AtkObject *accessible, + gpointer data); +static const gchar * unity_launcher_icon_accessible_get_name (AtkObject *obj); + + +#define UNITY_LAUNCHER_ICON_ACCESSIBLE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), UNITY_TYPE_LAUNCHER_ICON_ACCESSIBLE, UnityLauncherIconAccessiblePrivate)) + +G_DEFINE_TYPE (UnityLauncherIconAccessible, unity_launcher_icon_accessible, NUX_TYPE_OBJECT_ACCESSIBLE) + +struct _UnityLauncherIconAccessiblePrivate +{ +}; + +static void +unity_launcher_icon_accessible_class_init (UnityLauncherIconAccessibleClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); + + /* AtkObject */ + atk_class->initialize = unity_launcher_icon_accessible_initialize; + atk_class->get_name = unity_launcher_icon_accessible_get_name; + + g_type_class_add_private (gobject_class, sizeof (UnityLauncherIconAccessiblePrivate)); +} + +static void +unity_launcher_icon_accessible_init (UnityLauncherIconAccessible *launcher_icon_accessible) +{ + launcher_icon_accessible->priv = UNITY_LAUNCHER_ICON_ACCESSIBLE_GET_PRIVATE (launcher_icon_accessible); +} + +AtkObject* +unity_launcher_icon_accessible_new (nux::Object *object) +{ + AtkObject *accessible = NULL; + + g_return_val_if_fail (dynamic_cast<LauncherIcon *>(object), NULL); + + accessible = ATK_OBJECT (g_object_new (UNITY_TYPE_LAUNCHER_ICON_ACCESSIBLE, NULL)); + + atk_object_initialize (accessible, object); + + return accessible; +} + +/* AtkObject.h */ +static void +unity_launcher_icon_accessible_initialize (AtkObject *accessible, + gpointer data) +{ + ATK_OBJECT_CLASS (unity_launcher_icon_accessible_parent_class)->initialize (accessible, data); + + accessible->role = ATK_ROLE_PUSH_BUTTON; +} + + +static const gchar * +unity_launcher_icon_accessible_get_name (AtkObject *obj) +{ + const gchar *name; + + g_return_val_if_fail (UNITY_IS_LAUNCHER_ICON_ACCESSIBLE (obj), NULL); + + name = ATK_OBJECT_CLASS (unity_launcher_icon_accessible_parent_class)->get_name (obj); + if (name == NULL) + { + LauncherIcon *icon = NULL; + + icon = dynamic_cast<LauncherIcon *>(nux_object_accessible_get_object (NUX_OBJECT_ACCESSIBLE (obj))); + + if (icon == NULL) /* State is defunct */ + name = NULL; + else + name = icon->GetTooltipText().GetTCharPtr (); + } + + return name; +} diff --git a/src/unity-launcher-icon-accessible.h b/src/unity-launcher-icon-accessible.h new file mode 100644 index 000000000..fe50e0949 --- /dev/null +++ b/src/unity-launcher-icon-accessible.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +#ifndef UNITY_LAUNCHER_ICON_ACCESSIBLE_H +#define UNITY_LAUNCHER_ICON_ACCESSIBLE_H + +#include <atk/atk.h> + +#include "nux-object-accessible.h" + +G_BEGIN_DECLS + +#define UNITY_TYPE_LAUNCHER_ICON_ACCESSIBLE (unity_launcher_icon_accessible_get_type ()) +#define UNITY_LAUNCHER_ICON_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_TYPE_LAUNCHER_ICON_ACCESSIBLE, UnityLauncherIconAccessible)) +#define UNITY_LAUNCHER_ICON_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_TYPE_LAUNCHER_ICON_ACCESSIBLE, UnityLauncherIconAccessibleClass)) +#define UNITY_IS_LAUNCHER_ICON_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_TYPE_LAUNCHER_ICON_ACCESSIBLE)) +#define UNITY_IS_LAUNCHER_ICON_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_TYPE_LAUNCHER_ICON_ACCESSIBLE)) +#define UNITY_LAUNCHER_ICON_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_TYPE_LAUNCHER_ICON_ACCESSIBLE, UnityLauncherIconAccessibleClass)) + +typedef struct _UnityLauncherIconAccessible UnityLauncherIconAccessible; +typedef struct _UnityLauncherIconAccessibleClass UnityLauncherIconAccessibleClass; +typedef struct _UnityLauncherIconAccessiblePrivate UnityLauncherIconAccessiblePrivate; + +struct _UnityLauncherIconAccessible +{ + NuxObjectAccessible parent; + + /* < private > */ + UnityLauncherIconAccessiblePrivate *priv; +}; + +struct _UnityLauncherIconAccessibleClass +{ + NuxObjectAccessibleClass parent_class; +}; + +GType unity_launcher_icon_accessible_get_type (void); +AtkObject *unity_launcher_icon_accessible_new (nux::Object *object); + +G_END_DECLS + +#endif /* __UNITY_LAUNCHER_ICON_ACCESSIBLE_H__ */ diff --git a/src/unity-root-accessible.cpp b/src/unity-root-accessible.cpp new file mode 100644 index 000000000..5db980d5c --- /dev/null +++ b/src/unity-root-accessible.cpp @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +/** + * SECTION:unity-accessible-root + * @short_description: Root object for the UNITY accessible support + * + * #UnityRootAccessible is the root object of the accessibility + * tree-like hierarchy, exposing the application level. + * + * Implementation notes: FIXME, RIGHT NOW IS JUST A DUMMY IMPLEMENTATION + */ + +#include "unity-root-accessible.h" +#include "unitya11y.h" + +/* GObject */ +static void unity_root_accessible_class_init (UnityRootAccessibleClass *klass); +static void unity_root_accessible_init (UnityRootAccessible *root); +static void unity_root_accessible_finalize (GObject *object); + +/* AtkObject.h */ +static void unity_root_accessible_initialize (AtkObject *accessible, + gpointer data); +static gint unity_root_accessible_get_n_children (AtkObject *obj); +static AtkObject *unity_root_accessible_ref_child (AtkObject *obj, + gint i); +static AtkObject *unity_root_accessible_get_parent (AtkObject *obj); + + +#define UNITY_ROOT_ACCESSIBLE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), UNITY_TYPE_ROOT_ACCESSIBLE, UnityRootAccessiblePrivate)) + +G_DEFINE_TYPE (UnityRootAccessible, unity_root_accessible, ATK_TYPE_OBJECT) + +struct _UnityRootAccessiblePrivate +{ + /* we save on window_list the accessible object for the windows + registered */ + GSList *window_list; +}; + +static void +unity_root_accessible_class_init (UnityRootAccessibleClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); + + gobject_class->finalize = unity_root_accessible_finalize; + + /* AtkObject */ + atk_class->get_n_children = unity_root_accessible_get_n_children; + atk_class->ref_child = unity_root_accessible_ref_child; + atk_class->get_parent = unity_root_accessible_get_parent; + atk_class->initialize = unity_root_accessible_initialize; + + g_type_class_add_private (gobject_class, sizeof (UnityRootAccessiblePrivate)); +} + +static void +unity_root_accessible_init (UnityRootAccessible *root) +{ + root->priv = UNITY_ROOT_ACCESSIBLE_GET_PRIVATE (root); + + root->priv->window_list = NULL; +} + +AtkObject* +unity_root_accessible_new (void) +{ + AtkObject *accessible = NULL; + + accessible = ATK_OBJECT (g_object_new (UNITY_TYPE_ROOT_ACCESSIBLE, NULL)); + + atk_object_initialize (accessible, NULL); + + return accessible; +} + +static void +unity_root_accessible_finalize (GObject *object) +{ + UnityRootAccessible *root = UNITY_ROOT_ACCESSIBLE (object); + + g_return_if_fail (UNITY_IS_ROOT_ACCESSIBLE (object)); + + if (root->priv->window_list) + { + g_slist_free (root->priv->window_list); + root->priv->window_list = NULL; + } + + G_OBJECT_CLASS (unity_root_accessible_parent_class)->finalize (object); +} + +/* AtkObject.h */ +static void +unity_root_accessible_initialize (AtkObject *accessible, + gpointer data) +{ + accessible->role = ATK_ROLE_APPLICATION; + + // FIXME: compiz doesn't set the program name using g_set_prgname, + // and AFAIK, there isn't a way to get it. Requires further investigation. + // accessible->name = g_get_prgname(); + atk_object_set_name (accessible, "Unity"); + atk_object_set_parent (accessible, NULL); + + ATK_OBJECT_CLASS (unity_root_accessible_parent_class)->initialize (accessible, data); +} + +static gint +unity_root_accessible_get_n_children (AtkObject *obj) +{ + UnityRootAccessible *root = UNITY_ROOT_ACCESSIBLE (obj); + + return g_slist_length (root->priv->window_list); +} + +static AtkObject* +unity_root_accessible_ref_child (AtkObject *obj, + gint i) +{ + UnityRootAccessible *root = NULL; + gint num = 0; + AtkObject *item = NULL; + + root = UNITY_ROOT_ACCESSIBLE (obj); + num = atk_object_get_n_accessible_children (obj); + g_return_val_if_fail ((i < num)&&(i >= 0), NULL); + + item = ATK_OBJECT (g_slist_nth_data (root->priv->window_list, i)); + + if (!item) + return NULL; + + g_object_ref (item); + + return item; +} + +static AtkObject* +unity_root_accessible_get_parent (AtkObject *obj) +{ + return NULL; +} + + + +/* + * It adds a window to the internal window_list managed by the + * + * + * FIXME: third parties manually using this method should be + * temporal. This method should be a internal root method, as part of + * a basewindow::show callback, as in the case of gail + */ +void +unity_root_accessible_add_window (UnityRootAccessible *self, + nux::BaseWindow *window) +{ + AtkObject *window_accessible = NULL; + + g_return_if_fail (UNITY_IS_ROOT_ACCESSIBLE (self)); + + window_accessible = + unity_a11y_get_accessible (window); + + self->priv->window_list = + g_slist_append (self->priv->window_list, window_accessible); +} diff --git a/src/unity-root-accessible.h b/src/unity-root-accessible.h new file mode 100644 index 000000000..9e354a7ab --- /dev/null +++ b/src/unity-root-accessible.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +#ifndef UNITY_ROOT_ACCESSIBLE_H +#define UNITY_ROOT_ACCESSIBLE_H + +#include <atk/atk.h> + +#include "Nux/Nux.h" +#include "Nux/BaseWindow.h" + +G_BEGIN_DECLS + +#define UNITY_TYPE_ROOT_ACCESSIBLE (unity_root_accessible_get_type ()) +#define UNITY_ROOT_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_TYPE_ROOT_ACCESSIBLE, UnityRootAccessible)) +#define UNITY_ROOT_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_TYPE_ROOT_ACCESSIBLE, UnityRootAccessibleClass)) +#define UNITY_IS_ROOT_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_TYPE_ROOT_ACCESSIBLE)) +#define UNITY_IS_ROOT_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_TYPE_ROOT_ACCESSIBLE)) +#define UNITY_ROOT_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_TYPE_ROOT_ACCESSIBLE, UnityRootAccessibleClass)) + +typedef struct _UnityRootAccessible UnityRootAccessible; +typedef struct _UnityRootAccessibleClass UnityRootAccessibleClass; +typedef struct _UnityRootAccessiblePrivate UnityRootAccessiblePrivate; + +struct _UnityRootAccessible +{ + AtkObject parent; + + /* < private > */ + UnityRootAccessiblePrivate *priv; +}; + +struct _UnityRootAccessibleClass +{ + AtkObjectClass parent_class; +}; + +GType unity_root_accessible_get_type (void); +AtkObject *unity_root_accessible_new (void); + +void unity_root_accessible_add_window (UnityRootAccessible *self, nux::BaseWindow *window); + +G_END_DECLS + +#endif /* __UNITY_ROOT_ACCESSIBLE_H__ */ diff --git a/src/unity-util-accessible.cpp b/src/unity-util-accessible.cpp new file mode 100644 index 000000000..357eb2a56 --- /dev/null +++ b/src/unity-util-accessible.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +#include <stdlib.h> +#include <string.h> + +#include "unity-util-accessible.h" +#include "unity-root-accessible.h" + +static void unity_util_accessible_class_init (UnityUtilAccessibleClass *klass); +static void unity_util_accessible_init (UnityUtilAccessible *unity_util_accessible); + +/* atkutil.h */ + +static guint unity_util_accessible_add_global_event_listener (GSignalEmissionHook listener, + const gchar* event_type); +static void unity_util_accessible_remove_global_event_listener (guint remove_listener); +static guint unity_util_accessible_add_key_event_listener (AtkKeySnoopFunc listener, + gpointer data); +static void unity_util_accessible_remove_key_event_listener (guint remove_listener); +static AtkObject * unity_util_accessible_get_root (void); +static const gchar * unity_util_accessible_get_toolkit_name (void); +static const gchar * unity_util_accessible_get_toolkit_version (void); + + +static AtkObject* root = NULL; + +G_DEFINE_TYPE (UnityUtilAccessible, unity_util_accessible, ATK_TYPE_UTIL); + +static void +unity_util_accessible_class_init (UnityUtilAccessibleClass *klass) +{ + AtkUtilClass *atk_class; + gpointer data; + + data = g_type_class_peek (ATK_TYPE_UTIL); + atk_class = ATK_UTIL_CLASS (data); + + atk_class->add_global_event_listener = unity_util_accessible_add_global_event_listener; + atk_class->remove_global_event_listener = unity_util_accessible_remove_global_event_listener; + atk_class->add_key_event_listener = unity_util_accessible_add_key_event_listener; + atk_class->remove_key_event_listener = unity_util_accessible_remove_key_event_listener; + atk_class->get_root = unity_util_accessible_get_root; + atk_class->get_toolkit_name = unity_util_accessible_get_toolkit_name; + atk_class->get_toolkit_version = unity_util_accessible_get_toolkit_version; +} + +static void +unity_util_accessible_init (UnityUtilAccessible *unity_util_accessible) +{ + /* instance init: usually not required */ +} + +static AtkObject* +unity_util_accessible_get_root (void) +{ + if (!root) + root = unity_root_accessible_new (); + + return root; +} + +static const gchar * +unity_util_accessible_get_toolkit_name (void) +{ + return "UNITY"; +} + +static const gchar * +unity_util_accessible_get_toolkit_version (void) +{ + /* + * FIXME: + * Version is passed in as a -D flag when this file is + * compiled. + */ + return "0.1"; +} + + +static guint +unity_util_accessible_add_global_event_listener (GSignalEmissionHook listener, + const gchar* event_type) +{ + /* FIXME: implement me!! */ + return 0; +} + +static void +unity_util_accessible_remove_global_event_listener (guint remove_listener) +{ + /* FIXME: implement me!! */ +} + +static guint +unity_util_accessible_add_key_event_listener (AtkKeySnoopFunc listener, + gpointer data) +{ + /* FIXME: implement me!! */ + return 0; +} + +static void +unity_util_accessible_remove_key_event_listener (guint remove_listener) +{ + /* FIXME: implement me!! */ +} + + +void +unity_util_accessible_add_window (nux::BaseWindow *window) +{ + unity_root_accessible_add_window (UNITY_ROOT_ACCESSIBLE (root), + window); +} diff --git a/src/unity-util-accessible.h b/src/unity-util-accessible.h new file mode 100644 index 000000000..a1fcf180e --- /dev/null +++ b/src/unity-util-accessible.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +#ifndef UNITY_UTIL_ACCESSIBLE_H +#define UNITY_UTIL_ACCESSIBLE_H + +#include <atk/atk.h> + +#include "Nux/Nux.h" +#include "Nux/BaseWindow.h" + +G_BEGIN_DECLS + +#define UNITY_TYPE_UTIL_ACCESSIBLE (unity_util_accessible_get_type ()) +#define UNITY_UTIL_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_TYPE_UTIL_ACCESSIBLE, UnityUtilAccessible)) +#define UNITY_UTIL_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_TYPE_UTIL_ACCESSIBLE, UnityUtilAccessibleClass)) +#define UNITY_IS_UTIL_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_TYPE_UTIL_ACCESSIBLE)) +#define UNITY_IS_UTIL_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_TYPE_UTIL_ACCESSIBLE)) +#define UNITY_UTIL_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_TYPE_UTIL_ACCESSIBLE, UnityUtilAccessibleClass)) + +typedef struct _UnityUtilAccessible UnityUtilAccessible; +typedef struct _UnityUtilAccessibleClass UnityUtilAccessibleClass; +typedef struct _UnityUtilAccessiblePrivate UnityUtilAccessiblePrivate; + +struct _UnityUtilAccessible +{ + AtkUtil parent; + + /* < private > */ + UnityUtilAccessiblePrivate *priv; +}; + +struct _UnityUtilAccessibleClass +{ + AtkUtilClass parent_class; +}; + +GType unity_util_accessible_get_type (void); + +void unity_util_accessible_add_window (nux::BaseWindow *window); + +G_END_DECLS + +#endif /* UNITY_UTIL_ACCESSIBLE_H */ diff --git a/src/unitya11y.cpp b/src/unitya11y.cpp new file mode 100644 index 000000000..a66e4b0ed --- /dev/null +++ b/src/unitya11y.cpp @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +#include <glib.h> +#include <gio/gio.h> +#include <gmodule.h> +#include <stdio.h> + +#include "unitya11y.h" +#include "unity-util-accessible.h" + +/* nux accessible objects */ +#include "nux-view-accessible.h" +#include "nux-base-window-accessible.h" +#include "nux-layout-accessible.h" + +/* unity accessible objects */ +#include "Launcher.h" +#include "LauncherIcon.h" +#include "unity-launcher-accessible.h" +#include "unity-launcher-icon-accessible.h" + +static GHashTable *accessible_table = NULL; +/* FIXME: remove accessible objects when not required anymore */ + +static void +unity_a11y_restore_environment (void) +{ + g_unsetenv ("NO_AT_BRIDGE"); + g_unsetenv ("NO_GAIL"); +} + +static void +load_unity_atk_util () +{ + g_type_class_unref (g_type_class_ref (UNITY_TYPE_UTIL_ACCESSIBLE)); +} + +#define INIT_METHOD "gnome_accessibility_module_init" +#define DESKTOP_SCHEMA "org.gnome.desktop.interface" +#define ACCESSIBILITY_ENABLED_KEY "accessibility" +#define AT_SPI_SCHEMA "org.a11y.atspi" +#define ATK_BRIDGE_LOCATION_KEY "atk-bridge-location" + +static gboolean +has_gsettings_schema (gchar *schema) +{ + const char * const *list_schemas = NULL; + gboolean found = FALSE; + int i = 0; + + /* we need to check if AT_SPI_SCHEMA is present as g_setting_new + could abort if the schema is not here*/ + list_schemas = g_settings_list_schemas (); + for (i = 0; list_schemas [i]; i++) + { + if (!g_strcmp0 (list_schemas[i], schema)) + { + found = TRUE; + break; + } + } + + return found; +} + +static gboolean +should_enable_a11y (void) +{ + GSettings *desktop_settings = NULL; + gboolean value = FALSE; + + if (!has_gsettings_schema (DESKTOP_SCHEMA)) + return FALSE; + + desktop_settings = g_settings_new (DESKTOP_SCHEMA); + value = g_settings_get_boolean (desktop_settings, ACCESSIBILITY_ENABLED_KEY); + + g_object_unref (desktop_settings); + + return value; +} + +static gchar* +get_atk_bridge_path (void) +{ + GSettings *atspi_settings = NULL; + char *value = NULL; + + if (!has_gsettings_schema (AT_SPI_SCHEMA)) + return NULL; + + atspi_settings = g_settings_new (AT_SPI_SCHEMA); + value = g_settings_get_string (atspi_settings, ATK_BRIDGE_LOCATION_KEY); + + g_object_unref (atspi_settings); + + return value; +} + +static gboolean +a11y_invoke_module (const char *module_path) +{ + GModule *handle; + void (*invoke_fn) (void); + + if (!module_path) + { + g_warning ("Accessibility: invalid module path (NULL)"); + + return FALSE; + } + + if (!(handle = g_module_open (module_path, (GModuleFlags)0))) + { + g_warning ("Accessibility: failed to load module '%s': '%s'", + module_path, g_module_error ()); + + return FALSE; + } + + if (!g_module_symbol (handle, INIT_METHOD, (gpointer *)&invoke_fn)) + { + g_warning ("Accessibility: error library '%s' does not include " + "method '%s' required for accessibility support", + module_path, INIT_METHOD); + g_module_close (handle); + + return FALSE; + } + + invoke_fn (); + + return TRUE; +} + +/********************************************************************************/ +/* + * In order to avoid the atk-bridge loading and the GAIL + * initialization during the gtk_init, it is required to set some + * environment vars. + * + */ +void +unity_a11y_preset_environment (void) +{ + g_setenv ("NO_AT_BRIDGE", "1", TRUE); + g_setenv ("NO_GAIL", "1", TRUE); +} + +/* + * Initializes the accessibility (ATK) support on Unity + * + * It loads the atk-bridge if required. It checks: + * * If the proper gsettings keys are set + * * Loads the proper AtkUtil implementation + */ +void +unity_a11y_init (void) +{ + gchar *bridge_path = NULL; + + g_debug ("Unity accessibility initialization"); + + unity_a11y_restore_environment (); + + if (!should_enable_a11y ()) + return; + + load_unity_atk_util (); + + bridge_path = get_atk_bridge_path (); + + if (a11y_invoke_module (bridge_path)) + { + g_debug ("Unity accessibility started, using bridge on %s", + bridge_path); + } + + g_free (bridge_path); +} + +/* + * Finalize the related issues related with the accessibility. + * + * It mainly clean the resources related with the accessibility + */ +void +unity_a11y_finalize (void) +{ + if (accessible_table != NULL) + { + g_hash_table_unref (accessible_table); + accessible_table = NULL; + } +} + + +/* + * Creates the accessible object for a nux::Area object + * + * Method factory, equivalent to + * atk_object_factory_creeate_accessible, but required because + * AtkObjectFactory gives only support for GObject classes. + * + * FIXME: this should be a temporal method. The best way to implement + * that would be add a ->get_accessible method on the nux::View + * subclasses itself. + * + * WARNING: as a reason the previous comment it is true. Take into + * account that you should be careful with the order you add those + * defines. The order will be from more specific classes to more + * abstracted classes. + * + */ + +static AtkObject * +unity_a11y_create_accessible (nux::Object *object) +{ + /* UNITY classes*/ + if (object->Type().IsDerivedFromType (Launcher::StaticObjectType)) + return unity_launcher_accessible_new (object); + + if (object->Type().IsDerivedFromType (LauncherIcon::StaticObjectType)) + return unity_launcher_icon_accessible_new (object); + + /* NUX classes */ + if (object->Type().IsDerivedFromType (nux::BaseWindow::StaticObjectType)) + return nux_base_window_accessible_new (object); + + if (object->Type().IsDerivedFromType (nux::View::StaticObjectType)) + return nux_view_accessible_new (object); + + if (object->Type().IsDerivedFromType (nux::Layout::StaticObjectType)) + return nux_layout_accessible_new (object); + + if (object->Type().IsDerivedFromType (nux::Area::StaticObjectType)) + return nux_area_accessible_new (object); + + return nux_object_accessible_new (object); +} + +/* + * Returns the accessible object of a nux::View object + * + * This method tries to: + * * Check if area has already a accessibility object + * * If this is the case, returns that + * * If not, creates it and return the object + * + * FIXME: this should be a temporal method. The best way to implement + * that would be add a ->get_accessible method on the nux::View + * subclasses itself. + * + */ +AtkObject * +unity_a11y_get_accessible (nux::Object *object) +{ + AtkObject *accessible_object = NULL; + + g_return_val_if_fail (object != NULL, NULL); + + if (accessible_table == NULL) + { + accessible_table = g_hash_table_new (g_direct_hash, g_direct_equal); + } + + accessible_object = ATK_OBJECT (g_hash_table_lookup (accessible_table, object)); + if (accessible_object == NULL) + { + accessible_object = unity_a11y_create_accessible (object); + + g_hash_table_insert (accessible_table, object, accessible_object); + } + + return accessible_object; +} + diff --git a/src/unitya11y.h b/src/unitya11y.h new file mode 100644 index 000000000..8b2941d9f --- /dev/null +++ b/src/unitya11y.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2011 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * 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/>. + * + * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com> + */ + +#ifndef UNITY_A11Y_H +#define UNITY_A11Y_H + +#include <atk/atk.h> + +#include "Nux/Nux.h" +#include "NuxCore/Object.h" + +void unity_a11y_preset_environment (void); +void unity_a11y_init (void); +void unity_a11y_finalize (void); + +AtkObject *unity_a11y_get_accessible (nux::Object *object); + + +#endif /* UNITY_A11Y_H */ diff --git a/src/unityshell.cpp b/src/unityshell.cpp index 95d1d8191..d613976d7 100644 --- a/src/unityshell.cpp +++ b/src/unityshell.cpp @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* Compiz unity plugin * unity.cpp * @@ -39,6 +40,12 @@ #include <core/atoms.h> +#include "unitya11y.h" + +/* FIXME: once we get a better method to add the toplevel windows to + the accessible root object, this include would not be required */ +#include "unity-util-accessible.h" + #include "../libunity/perf-logger-utility.h" /* Set up vtable symbols */ @@ -100,10 +107,10 @@ UnityScreen::paintDisplay (const CompRegion ®ion) /* called whenever we need to repaint parts of the screen */ bool UnityScreen::glPaintOutput (const GLScreenPaintAttrib &attrib, - const GLMatrix &transform, - const CompRegion ®ion, - CompOutput *output, - unsigned int mask) + const GLMatrix &transform, + const CompRegion ®ion, + CompOutput *output, + unsigned int mask) { bool ret; @@ -124,10 +131,10 @@ UnityScreen::glPaintOutput (const GLScreenPaintAttrib &attrib, void UnityScreen::glPaintTransformedOutput (const GLScreenPaintAttrib &attrib, - const GLMatrix &transform, - const CompRegion ®ion, - CompOutput *output, - unsigned int mask) + const GLMatrix &transform, + const CompRegion ®ion, + CompOutput *output, + unsigned int mask) { allowWindowPaint = false; gScreen->glPaintOutput (attrib, transform, region, output, mask); @@ -161,6 +168,18 @@ UnityScreen::damageNuxRegions () void UnityScreen::handleEvent (XEvent *event) { + switch (event->type) + { + case FocusIn: + case FocusOut: + if (event->xfocus.mode == NotifyGrab) + PluginAdapter::Default ()->OnScreenGrabbed (); + else if (event->xfocus.mode == NotifyUngrab) + PluginAdapter::Default ()->OnScreenUngrabbed (); + + break; + } + screen->handleEvent (event); if (screen->otherGrabExist ("deco", "move", NULL)) @@ -169,6 +188,27 @@ UnityScreen::handleEvent (XEvent *event) } } +bool +UnityScreen::showLauncherKeyInitiate (CompAction *action, + CompAction::State state, + CompOption::Vector &options) +{ + // to receive the Terminate event + if (state & CompAction::StateInitKey) + action->setState (action->state () | CompAction::StateTermKey); + + launcher->ForceShowLauncherStart (); + return false; +} + +bool +UnityScreen::showLauncherKeyTerminate (CompAction *action, + CompAction::State state, + CompOption::Vector &options) +{ + launcher->ForceShowLauncherEnd (); + return false; +} gboolean UnityScreen::initPluginActions (gpointer data) @@ -179,30 +219,50 @@ UnityScreen::initPluginActions (gpointer data) if (p) { + MultiActionList expoActions (0); + foreach (CompOption &option, p->vTable->getOptions ()) { - if (option.name () == "expo_key") + if (option.name () == "expo_key" || + option.name () == "expo_button" || + option.name () == "expo_edge") { CompAction *action = &option.value ().action (); - PluginAdapter::Default ()->SetExpoAction (action); + expoActions.AddNewAction (action); break; } } + + PluginAdapter::Default ()->SetExpoAction (expoActions); } p = CompPlugin::find ("scale"); if (p) { + MultiActionList scaleActions (0); + foreach (CompOption &option, p->vTable->getOptions ()) { - if (option.name () == "initiate_all_key") + if (option.name () == "initiate_all_key" || + option.name () == "initiate_all_button" || + option.name () == "initiate_all_edge" || + option.name () == "initiate_key" || + option.name () == "initiate_button" || + option.name () == "initiate_edge" || + option.name () == "initiate_group_key" || + option.name () == "initiate_group_button" || + option.name () == "initiate_group_edge" || + option.name () == "initiate_output_key" || + option.name () == "initiate_output_button" || + option.name () == "initiate_output_edge") { CompAction *action = &option.value ().action (); - PluginAdapter::Default ()->SetScaleAction (action); - break; + scaleActions.AddNewAction (action); } } + + PluginAdapter::Default ()->SetScaleAction (scaleActions); } return FALSE; @@ -245,8 +305,7 @@ UnityScreen::getWindowPaintList () if (std::find (xwns.begin (), xwns.end (), (*it)->id ()) != xwns.end ()) { - CompWindowList::iterator pit = it; - pl.erase (pit); + it = pl.erase (it); } } @@ -261,10 +320,10 @@ UnityScreen::getWindowPaintList () * and if so paint nux and stop us from painting * other windows or on top of the whole screen */ bool -UnityWindow::glDraw (const GLMatrix &matrix, - GLFragment::Attrib &attrib, - const CompRegion ®ion, - unsigned int mask) +UnityWindow::glDraw (const GLMatrix &matrix, + GLFragment::Attrib &attrib, + const CompRegion ®ion, + unsigned int mask) { if (uScreen->doShellRepaint && uScreen->allowWindowPaint) { @@ -349,7 +408,7 @@ UnityScreen::onRedrawRequested () /* Handle option changes and plug that into nux windows */ void UnityScreen::optionChanged (CompOption *opt, - UnityshellOptions::Options num) + UnityshellOptions::Options num) { switch (num) { @@ -357,8 +416,14 @@ UnityScreen::optionChanged (CompOption *opt, launcher->SetAutohide (optionGetLauncherAutohide (), (nux::View *) panelView->HomeButton ()); break; - case UnityshellOptions::LauncherFloat: - launcher->SetFloating (optionGetLauncherFloat ()); + case UnityshellOptions::BacklightAlwaysOn: + launcher->SetBacklightAlwaysOn (optionGetBacklightAlwaysOn ()); + break; + case UnityshellOptions::LaunchAnimation: + launcher->SetLaunchAnimation ((Launcher::LaunchAnimation) optionGetLaunchAnimation ()); + break; + case UnityshellOptions::UrgentAnimation: + launcher->SetUrgentAnimation ((Launcher::UrgentAnimation) optionGetUrgentAnimation ()); break; default: break; @@ -385,6 +450,9 @@ UnityScreen::UnityScreen (CompScreen *screen) : g_thread_init (NULL); dbus_g_thread_init (); + + unity_a11y_preset_environment (); + gtk_init (NULL, NULL); XSetErrorHandler (old_handler); @@ -407,13 +475,19 @@ UnityScreen::UnityScreen (CompScreen *screen) : wt->RedrawRequested.connect (sigc::mem_fun (this, &UnityScreen::onRedrawRequested)); + unity_a11y_init (); + wt->Run (NULL); uScreen = this; - debugger = new IntrospectionDBusInterface (this); + debugger = new DebugDBusInterface (this); - optionSetLauncherAutohideNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); - optionSetLauncherFloatNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); + optionSetLauncherAutohideNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); + optionSetBacklightAlwaysOnNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); + optionSetLaunchAnimationNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); + optionSetUrgentAnimationNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); + optionSetShowLauncherInitiate (boost::bind (&UnityScreen::showLauncherKeyInitiate, this, _1, _2, _3)); + optionSetShowLauncherTerminate (boost::bind (&UnityScreen::showLauncherKeyTerminate, this, _1, _2, _3)); g_timeout_add (0, &UnityScreen::initPluginActions, this); g_timeout_add (5000, (GSourceFunc) write_logger_data_to_disk, NULL); @@ -422,6 +496,7 @@ UnityScreen::UnityScreen (CompScreen *screen) : UnityScreen::~UnityScreen () { + unity_a11y_finalize (); } /* Can't create windows until after we have initialized everything */ @@ -470,7 +545,12 @@ void UnityScreen::initLauncher (nux::NThread* thread, void* InitData) self->launcherWindow->EnableInputWindow(true); self->launcherWindow->InputWindowEnableStruts(true); + /* FIXME: this should not be manual, should be managed with a + show/hide callback like in GAIL*/ + unity_util_accessible_add_window (self->launcherWindow); + self->launcher->SetIconSize (54, 48); + self->launcher->SetBacklightAlwaysOn (true); LOGGER_END_PROCESS ("initLauncher-Launcher"); /* Setup panel */ @@ -500,6 +580,9 @@ void UnityScreen::initLauncher (nux::NThread* thread, void* InitData) /* Setup Places */ self->placesController = new PlacesController (); + self->launcher->SetAutohide (true, (nux::View *) self->panelView->HomeButton ()); + self->launcher->SetLaunchAnimation (Launcher::LAUNCH_ANIMATION_PULSE); + self->launcher->SetUrgentAnimation (Launcher::URGENT_ANIMATION_WIGGLE); g_timeout_add (2000, &UnityScreen::strutHackTimeout, self); END_FUNCTION (); diff --git a/src/unityshell.h b/src/unityshell.h index 6062e16d5..1cb74fd55 100644 --- a/src/unityshell.h +++ b/src/unityshell.h @@ -1,3 +1,4 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* Compiz unity plugin * unity.h * @@ -31,7 +32,7 @@ #include "LauncherController.h" #include "PanelView.h" #include "PlacesController.h" -#include "IntrospectionDBusInterface.h" +#include "DebugDBusInterface.h" #include <Nux/WindowThread.h> #include <sigc++/sigc++.h> @@ -90,6 +91,14 @@ class UnityScreen : /* handle X11 events */ void handleEvent (XEvent *); + + bool + showLauncherKeyInitiate (CompAction *action, CompAction::State state, + CompOption::Vector &options); + + bool + showLauncherKeyTerminate (CompAction *action, CompAction::State state, + CompOption::Vector &options); /* handle option changes and change settings inside of the * panel and dock views */ @@ -138,7 +147,7 @@ class UnityScreen : nux::BaseWindow *launcherWindow; nux::BaseWindow *panelWindow; nux::Geometry lastTooltipArea; - IntrospectionDBusInterface *debugger; + DebugDBusInterface *debugger; /* handle paint order */ bool doShellRepaint; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 55eb3e070..9ff6b11bc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -70,6 +70,8 @@ add_executable (test-panel ../src/PanelIndicatorObjectView.h ../src/PanelIndicatorObjectEntryView.cpp ../src/PanelIndicatorObjectEntryView.h + ../src/PanelTitlebarGrabAreaView.h + ../src/PanelTitlebarGrabAreaView.cpp ../src/IndicatorObjectFactory.h ../src/IndicatorObjectProxy.h ../src/IndicatorObjectEntryProxy.h diff --git a/tests/unit/TestMain.cpp b/tests/unit/TestMain.cpp index da2b04861..da2b04861 100755..100644 --- a/tests/unit/TestMain.cpp +++ b/tests/unit/TestMain.cpp diff --git a/tests/unit/TestQuicklistMenuitems.cpp b/tests/unit/TestQuicklistMenuitems.cpp index 9018cac9c..9018cac9c 100755..100644 --- a/tests/unit/TestQuicklistMenuitems.cpp +++ b/tests/unit/TestQuicklistMenuitems.cpp diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 523e56f65..d0165a15e 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,7 +1,7 @@ # # Some unity tools # -install(FILES makebootchart.py migrate_favorites.py PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/unity/) +install(FILES makebootchart.py migrate_favorites.py autopilot.py PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/unity/) configure_file (${CMAKE_CURRENT_SOURCE_DIR}/unity.cmake ${CMAKE_BINARY_DIR}/bin/unity) install(FILES ${CMAKE_BINARY_DIR}/bin/unity PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ diff --git a/tools/autopilot.py b/tools/autopilot.py new file mode 100755 index 000000000..5cd006d25 --- /dev/null +++ b/tools/autopilot.py @@ -0,0 +1,221 @@ +#!/usr/bin/python +# +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- +# Copyright 2010 Canonical +# Author: Alex Launi +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 3, as published +# by the Free Software Foundation. +# +# This script is designed to run unity in a test drive manner. It will drive +# X and test the GL calls that Unity makes, so that we can easily find out if +# we are triggering graphics driver/X bugs. + +import subprocess +from sys import exit +from time import sleep + +import dbus +from Xlib import X +from Xlib.display import Display +from Xlib.ext.xtest import fake_input + +class UnityUtil(object): + '''Utility class for running, and poking into Unity. + Someday when dbus is working again we can have it get launcher info from here + for now we can just fake it and guess.''' + + UNITY_BUS_NAME = 'com.canonical.Unity' + INTROSPECTION_PATH = '/com/canonical/Unity/Debug' + INTROSPECTION_IFACE = 'com.canonical.Unity.Debug.Introspection' + + def __init__(self): + self._bus = dbus.SessionBus() + self._introspection_proxy_obj = self._bus.get_object(self.UNITY_BUS_NAME, self.INTROSPECTION_PATH) + self._introspection_iface = dbus.Interface(self._introspection_proxy_obj, + self.INTROSPECTION_IFACE) + + def run_unity(self): + ''' Runs unity with --reset to ensure that a default Unity/compiz session + is being tested. If unity --reset does not return 0, a CalledProcessError + will be raised. No exception does not mean that everything is ok, is_running + should still be called after.''' + ret = subprocess.check_call ('unity', '--reset') + + + def is_running(self): + '''Checks if Unity is running by examing the session bus, and checking if + 'com.canonical.Unity' is currently owned.''' + return self._bus.name_has_owner(self.UNITY_BUS_NAME) + +class Mouse(object): + '''Wrapper around xlib to make moving the mouse easier''' + + def __init__(self): + self._display = Display() + + def press(self, button=1): + '''Press mouse button at current mouse location''' + fake_input(self._display, X.ButtonPress, button) + self._display.sync() + + def release(self, button=1): + '''Releases mouse button at current mouse location''' + fake_input(self._display, X.ButtonRelease, button) + self._display.sync() + + def click(self, button=1): + '''Click mouse at current location''' + self.press(button) + sleep(0.25) + self.release(button) + + def move(self, x, y): + '''Moves mouse to location (x, y)''' + def perform_move(x, y): + fake_input(self._display, X.MotionNotify, x=x, y=y) + self._display.sync() + sleep(0.001) + + dest_x, dest_y = x, y + curr_x, curr_y = self.position() + + # calculate a path from our current position to our destination + dy = float(curr_y - dest_y) + dx = float(curr_x - dest_x) + slope = dy/dx if dx > 0 else 0 + yint = curr_y - (slope * curr_x) + xscale = 1 if dest_x > curr_x else -1 + + while (int(curr_x) != dest_x): + curr_x += xscale; + curr_y = int(slope * curr_x + yint) if curr_y > 0 else dest_y + + perform_move(curr_x, curr_y) + + if (curr_y != dest_y): + yscale = 1 if dest_y > curr_y else -1 + while (curr_y != dest_y): + curr_y += yscale + perform_move(curr_x, curr_y) + + + def position(self): + '''Returns the current position of the mouse pointer''' + coord = self._display.screen().root.query_pointer()._data + x, y = coord["root_x"], coord["root_y"] + return x, y + + def reset(self): + fake_input (self._display, X.MotionNotify, x = 800, y = 500) + self._display.sync() + +class UnityTests(object): + '''Runs a series of unity actions, triggering GL calls''' + + # this is totally lame. This should not be hard coded, but until I can get + # unity to run in gdb and debug why introspection is crashing and hardlocking + # this is the best I can do. + _dest_x = 32 + _dest_y = 57 + + def __init__(self): + self._mouse = Mouse() + self._unity = UnityUtil() + + def show_tooltip(self): + '''Move mouse to a launcher and hover to show the tooltip''' + print 'Showing tool tip...' + self._mouse.reset() + self._mouse.move(self._dest_x, self._dest_y) + return self._unity.is_running() + + def show_quicklist(self): + '''Move mouse to a launcher and right click''' + print 'Showing quicklist...' + self._mouse.reset() + self._mouse.move(self._dest_x, self._dest_y) + sleep(0.25) + self._mouse.click(button=3) + sleep(2) + # hides quicklist + self._mouse.click(button=3) + return self._unity.is_running() + + def drag_launcher(self): + '''Click a launcher icon and drag down to move the whole launcher''' + print 'Dragging entire launcher...' + self._mouse.reset() + self._mouse.move(self._dest_x, self._dest_y) + sleep(0.25) + print self._mouse.position() + print 'pressing' + self._mouse.press() + self._mouse.move(self._dest_x, self._dest_y + 300) + sleep(0.25) + print 'releasing' + self._mouse.release() + return self._unity.is_running() + + def drag_launcher_icon_along_edge_drop(self): + '''Click a launcher icon and drag it along the edge of the launcher + to test moving icons around on the launcher''' + print 'Moving launcher icon along edge...' + self._mouse.reset() + self._mouse.move(self._dest_x, self._dest_y) + self._mouse.press() + self._mouse.move(self._dest_x + 25, self._dest_y) + self._mouse.move(self._dest_x + 25, self._dest_y + 500) + self._mouse.release() + return self._unity.is_running() + + def drag_launcher_icon_out_and_drop(self): + '''Click a launcher icon and drag it straight out so that when dropped + it returns to its original position''' + print 'Dragging launcher straight out and dropping...' + self._mouse.reset() + self._mouse.move(self._dest_x, self._dest_y) + self._mouse.press() + self._mouse.move(self._dest_x + 300, self._dest_y) + self._mouse.release() + return self._unity.is_running() + + def drag_launcher_icon_out_and_move(self): + '''Click a launcher icon and drag it diagonally so that it changes position''' + print 'Dragging a launcher icon out, and moving it...''' + self._mouse.reset() + self._mouse.move(self._dest_x, self._dest_y) + self._mouse.press() + self._mouse.move(self._dest_x + 300, self._dest_y) + self._mouse.move(self._dest_x + 300, self._dest_y + 300) + self._mouse.release() + return self._unity.is_running() + +if __name__ == "__main__": + tests = UnityTests() + if (not tests.show_tooltip()): + print 'FAIL: SHOW TOOLTIP CRASHED UNITY' + exit (1) + sleep(1.5) + if (not tests.show_quicklist()): + print 'FAIL: SHOW QUICKLIST CRASHED UNITY' + exit (1) + sleep(1.5) + if (not tests.drag_launcher()): + print 'FAIL: DRAG LAUNCHER CRASHED UNITY' + exit (1) + sleep(1.5) + if (not tests.drag_launcher_icon_along_edge_drop()): + print 'FAIL: DRAG LAUNCHER ICON ALONG EDGE CRASHED UNITY' + exit (1) + sleep(1.5) + if (not tests.drag_launcher_icon_out_and_drop()): + print 'FAIL: DRAG LAUNCHER ICON OUT AND DROP CRASHED UNITY' + exit (1) + sleep(1.5) + if (not tests.drag_launcher_icon_out_and_move()): + print 'FAIL: DRAG LAUNCHER ICON OUT AND MOVE CRASHED UNITY' + exit (1) + + print 'PASS' diff --git a/tools/migrate_favorites.py b/tools/migrate_favorites.py index ab0e62b47..8878cb80a 100755 --- a/tools/migrate_favorites.py +++ b/tools/migrate_favorites.py @@ -16,7 +16,7 @@ import sys import subprocess from xdg import BaseDirectory -LAST_MIGRATION = '3.2.0' +LAST_MIGRATION = '3.2.10' def get_log_file(): ''' open the log file and return it ''' @@ -32,7 +32,7 @@ def get_log_file(): def migrating_chapter_log(name, apps_list, migration_list, log_file): '''Log migration of new launchers''' - log(" Migration for %s.\n Current app list is: %s\n Candidates are: %s" % (name, apps_list, migration_list), log_file) + log(" + Migration for %s.\n Current app list is: %s\n Candidates are: %s" % (name, apps_list, migration_list), log_file) def log(message, log_file): @@ -67,10 +67,15 @@ def register_new_app(launcher_location, apps_list, log_file): # default distribution launcher don't go into that function (as don't have an aboslute path) entry = "" if os.path.exists(launcher_location): - log(" == %s: exists" % launcher_location, log_file) + log(" == %s: exists" % launcher_location, log_file) # try to strip the full path we had in unity mutter if it's part of a xdg path: # or try to get that for other desktop file based on name. candidate_desktop_filename = launcher_location.split("/")[-1] + # some desktop file with modified exec key (like in cairo-dock contains 01desktopfilename.desktop, strip that) + try: + candidate_cairodock_desktop_filename = candidate_desktop_filename.split("01")[1] + except IndexError: + candidate_cairodock_desktop_filename = "" for xdg_dir in BaseDirectory.xdg_data_dirs: xdg_app_dir = os.path.join(xdg_dir, "applications", "") if launcher_location.startswith(xdg_app_dir): @@ -78,25 +83,66 @@ def register_new_app(launcher_location, apps_list, log_file): # if really the xdg path is the path to the launcher if not '/' in candidate_desktop_file: entry = candidate_desktop_file + log(" Direct match found for system desktop file", log_file) break # second chance: try to see if the desktop filename is in xdg path and so, assume it's a match - if os.path.exists("%s/%s" % (xdg_app_dir, candidate_desktop_filename)): + if not entry and os.path.exists("%s/%s" % (xdg_app_dir, candidate_desktop_filename)): entry = candidate_desktop_filename + log(" Similar desktop file name with system desktop file", log_file) break + # third chance: try to see if a tweaked cairo-dock like deskto file name is in xdg path + if not entry and os.path.exists("%s/%s" % (xdg_app_dir, candidate_cairodock_desktop_filename)): + entry = candidate_cairodock_desktop_filename + log(" Similar Cairo-Dock -like desktop file name with system desktop file", log_file) + break + # fourth and last chance: try to find a corresponding Exec key. + # Wait! scanning /usr/share/applications is heavy !!! + # Don't panic, we have the bamf.index for that :) + if not entry: + exec_arg = "" + try: + for line in open(launcher_location): + if "Exec=" in line: + exec_arg = line.split("Exec=")[1] + break + except IOError: + log(" Can't open %s for reading Exec" % launcher_location, log_file) + if exec_arg: + try: + for line in open("/usr/share/applications/bamf.index"): + if exec_arg in line: + entry = line.split()[0] + log(" Coherent exec key found with system desktop file", log_file) + break + except IOError: + log(" No bamf.index file found on the system!", log_file) if not entry: entry = launcher_location - log(" %s: real entry is %s" % (launcher_location, entry), log_file) + log(" %s: real entry is %s" % (launcher_location, entry), log_file) if entry not in apps_list: - log(" --- adding %s as not in app_list" % entry, log_file) + log(" --- adding %s as not in app_list" % entry, log_file) apps_list.append(entry) else: - log(" --- NOT adding %s as already in app_list" % entry, log_file) + log(" --- NOT adding %s as already in app_list" % entry, log_file) else: - log(" == %s: doesn't exist" % launcher_location, log_file) + log(" == %s: doesn't exist" % launcher_location, log_file) return apps_list +def save_gsettings_favorites(apps_list, log_file): + ''' save the app list favorites to gsettings ''' + + #print apps_list + return_code = subprocess.call(["gsettings", "set", "com.canonical.Unity.Launcher", "favorites", str(apps_list)]) + + if return_code != 0: + print "Settings fail to transition to new unity compiz favorites" + log("Settings fail to transition to new unity compiz favorites\n\n", log_file) + if log_file: + log_file.close() + sys.exit(1) + try: migration_level = subprocess.Popen(["gsettings", "get", "com.canonical.Unity.Launcher", "favorite-migration"], stdout=subprocess.PIPE).communicate()[0].strip()[1:-1] except OSError, e: @@ -162,29 +208,56 @@ if migration_level < '3.2.0': # get GNOME desktop launchers desktop_dir = get_desktop_dir() desktop_items = glob.glob('%s/*.desktop' % desktop_dir) - migrating_chapter_log("deskop items in %s" % desktop_dir, apps_list, desktop_items, log_file) + migrating_chapter_log("desktop items in %s" % desktop_dir, apps_list, desktop_items, log_file) for launcher_location in glob.glob('%s/*.desktop' % desktop_dir): # blacklist ubiquity as will have two ubiquity in the netbook live session then if not "ubiquity" in launcher_location: apps_list = register_new_app(launcher_location, apps_list, log_file) # Now write to gsettings! - #print apps_list - return_code = subprocess.call(["gsettings", "set", "com.canonical.Unity.Launcher", "favorites", str(apps_list)]) - - if return_code != 0: - print "Settings fail to transition to new unity compiz" - log("Settings fail to transition to new unity compiz\n\n", log_file) - if log_file: - log_file.close() - sys.exit(1) + save_gsettings_favorites(apps_list, log_file) # some autumn cleanage (gconf binding for recursive_unset seems broken) subprocess.call(["gconftool-2", "--recursive-unset", "/apps/netbook-launcher"]) subprocess.call(["gconftool-2", "--recursive-unset", "/desktop/unity"]) - print "Settings successfully transitionned to new unity compiz" -log("Migration script ended sucessfully\n\n", log_file) +# second migration: transition popular docks entry as well +if migration_level < '3.2.10': + log("======= Migration to 3.2.10 =======\n", log_file) + + # import awn favorites + awn_favorites_list = client.get_list('/apps/awn-applet-taskmanager/launcher_paths', gconf.VALUE_STRING) + migrating_chapter_log("awn favorites", apps_list, awn_favorites_list, log_file) + for launcher_location in awn_favorites_list: + apps_list = register_new_app(launcher_location, apps_list, log_file) + + # import Docky favorites + dock_list = client.get_list('/apps/docky-2/Docky/DockController/ActiveDocks', gconf.VALUE_STRING) + for dock in dock_list: + docky_favorites_list = client.get_list('/apps/docky-2/Docky/Interface/DockPreferences/%s/Launchers' % dock, gconf.VALUE_STRING) + migrating_chapter_log("Docky favorites for %s" % dock, apps_list, docky_favorites_list, log_file) + for launcher_location in docky_favorites_list: + try: + launcher_location = launcher_location.split("file://")[1] + except IndexError: + pass + apps_list = register_new_app(launcher_location, apps_list, log_file) + + # import Cairo-Dock favorites + try: + cairodock_path = "%s/cairo-dock/current_theme/launchers" % BaseDirectory.xdg_config_home + cairodock_favorites_list = os.listdir(cairodock_path) + migrating_chapter_log("Cairo-Dock favorites (in %s)" % cairodock_path, apps_list, cairodock_favorites_list, log_file) + for launcher in cairodock_favorites_list: + launcher_location = "%s/%s" % (cairodock_path, launcher) + apps_list = register_new_app(launcher_location, apps_list, log_file) + except OSError: + log(" + Can't migrate Cairo-Dock as %s doesn't exist" % cairodock_path, log_file) + + # Now write to gsettings! + save_gsettings_favorites(apps_list, log_file) + +log("Migration script ended successfully\n\n", log_file) if log_file: log_file.close() diff --git a/tools/unity.cmake b/tools/unity.cmake index 5c5ccc352..6dfb75174 100755 --- a/tools/unity.cmake +++ b/tools/unity.cmake @@ -114,6 +114,8 @@ if __name__ == '__main__': help="Run unity under debugging to help debugging an issue. /!\ Only if devs ask for it.") parser.add_option("--log", action="store", help="Store log under filename.") + parser.add_option("--replace", action="store_true", + help="Run unity /!\ This is for compatibility with other desktop interfaces and acts the same as running unity without --replace") parser.add_option("--reset", action="store_true", help="Reset the unity profile in compiz and restart it.") parser.add_option("-v", "--verbose", action="store_true", @@ -123,5 +125,8 @@ if __name__ == '__main__': set_unity_env() if options.reset: reset_unity_compiz_profile () - + + if options.replace: + print ("WARNING: This is for compatibility with other desktop interfaces please use unity without --replace") + run_unity (options.verbose, options.advanced_debug, args, options.log) diff --git a/unityshell.xml.in b/unityshell.xml.in index a35cbfdfc..aac85f35c 100644 --- a/unityshell.xml.in +++ b/unityshell.xml.in @@ -1,52 +1,101 @@ <?xml version="1.0" encoding="UTF-8"?> <compiz> <plugin name="unityshell" useBcop="true"> - <_short>Ubuntu Unity Plugin</_short> - <_long>Plugin to draw the Unity Shell</_long> - <category>Desktop</category> - <deps> - <relation type="after"> - <plugin>bailer</plugin> - <plugin>detection</plugin> - <plugin>composite</plugin> - <plugin>opengl</plugin> - <plugin>mousepoll</plugin> - <plugin>move</plugin> - <plugin>resize</plugin> - <plugin>decor</plugin> - <plugin>compiztoolbox</plugin> - <plugin>place</plugin> - <plugin>session</plugin> - <plugin>animation</plugin> - <plugin>regex</plugin> - <plugin>cube</plugin> - <plugin>rotate</plugin> - <plugin>cubeaddon</plugin> - <plugin>gnomecompat</plugin> - <plugin>vpswitch</plugin> - <plugin>fade</plugin> - <plugin>staticswitcher</plugin> - <plugin>scale</plugin> - <plugin>expo</plugin> - <plugin>ezoom</plugin> - <plugin>wall</plugin> - </relation> - <requirement> - <plugin>opengl</plugin> - <plugin>wall</plugin> - </requirement> - </deps> - <options> - <option name="launcher_autohide" type="bool"> - <_short>Autohide Launcher</_short> - <_long>Make the launcher hide automatically after some time inactive</_long> - <default>false</default> - </option> - <option name="launcher_float" type="bool"> - <_short>Float Launcher</_short> - <_long>Make the launcher appear above other windows</_long> - <default>false</default> - </option> - </options> + <_short>Ubuntu Unity Plugin</_short> + <_long>Plugin to draw the Unity Shell</_long> + <category>Desktop</category> + <deps> + <relation type="after"> + <plugin>bailer</plugin> + <plugin>detection</plugin> + <plugin>composite</plugin> + <plugin>opengl</plugin> + <plugin>mousepoll</plugin> + <plugin>move</plugin> + <plugin>resize</plugin> + <plugin>decor</plugin> + <plugin>compiztoolbox</plugin> + <plugin>place</plugin> + <plugin>session</plugin> + <plugin>animation</plugin> + <plugin>regex</plugin> + <plugin>cube</plugin> + <plugin>rotate</plugin> + <plugin>cubeaddon</plugin> + <plugin>gnomecompat</plugin> + <plugin>vpswitch</plugin> + <plugin>fade</plugin> + <plugin>staticswitcher</plugin> + <plugin>scale</plugin> + <plugin>expo</plugin> + <plugin>ezoom</plugin> + <plugin>wall</plugin> + </relation> + <requirement> + <plugin>opengl</plugin> + <plugin>wall</plugin> + </requirement> + </deps> + <options> + <group> + <_short>Behaviour</_short> + <option name="launcher_autohide" type="bool"> + <_short>Autohide Launcher</_short> + <_long>Make the launcher hide automatically after some time inactive</_long> + <default>true</default> + </option> + <option name="show_launcher" type="key"> + <_short>Key to show the launcher</_short> + <_long>Make the launcher appear with that key</_long> + <default><Super></default> + </option> + </group> + <group> + <_short>Experimental</_short> + <option name="backlight_always_on" type="bool"> + <_short>Backlight Always On</_short> + <_long>Make the launcher icons always have a backlight</_long> + <default>true</default> + </option> + <option name="launch_animation" type="int"> + <_short>Launch Animation</_short> + <_long>Animation played when a launcher icon is in the process of spawning a process</_long> + <min>0</min> + <max>2</max> + <default>1</default> + <desc> + <value>0</value> + <_name>None</_name> + </desc> + <desc> + <value>1</value> + <_name>Pulse Until Running</_name> + </desc> + <desc> + <value>2</value> + <_name>Blink</_name> + </desc> + </option> + <option name="urgent_animation" type="int"> + <_short>Urgent Animation</_short> + <_long>Animation played when a launcher icon is in the urgent state</_long> + <min>0</min> + <max>2</max> + <default>2</default> + <desc> + <value>0</value> + <_name>None</_name> + </desc> + <desc> + <value>1</value> + <_name>Pulse</_name> + </desc> + <desc> + <value>2</value> + <_name>Wiggle</_name> + </desc> + </option> + </group> + </options> </plugin> </compiz> |
