diff options
| -rw-r--r-- | AUTHORS | 4 | ||||
| -rw-r--r-- | LICENSE | 2 | ||||
| -rw-r--r-- | LICENSE.GPL | 339 | ||||
| -rw-r--r-- | README.md | 19 | ||||
| -rw-r--r-- | shell/clock.c | 42 | ||||
| -rw-r--r-- | shell/clock.h | 9 | ||||
| -rw-r--r-- | shell/favorites.c | 10 | ||||
| -rw-r--r-- | shell/maynard.c | 747 | ||||
| -rw-r--r-- | shell/panel.c | 87 | ||||
| -rw-r--r-- | shell/panel.h | 8 | ||||
| -rw-r--r-- | shell/style.css | 2 |
11 files changed, 885 insertions, 384 deletions
@@ -0,0 +1,4 @@ +Emilio Pozuelo Monfort <emilio.pozuelo@collabora.co.uk> +Jonny Lamb <jonny.lamb@collabora.co.uk> +Marco Barisione <marco.barisione@collabora.co.uk> +Tiago Vignatti <tiago.vignatti@intel.com> @@ -39,3 +39,5 @@ All other files are licensed under the GPL 2+ license: License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Full text of the GPL 2+ license can be found in the LICENSE.GPL file.
\ No newline at end of file diff --git a/LICENSE.GPL b/LICENSE.GPL new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/LICENSE.GPL @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. @@ -3,20 +3,5 @@ This is a desktop shell client for Weston based on GTK. It was based on weston-gtk-shell, a project by Tiago Vignatti. -## Original idea - -The idea is that this client, or any other based on any toolkit, can -interchangeably be used with a single desktop plugin like the [weston desktop -plugin](https://github.com/tiagovignatti/weston-desktop-plugin). Therefore, -one compositor, with a single desktop plugin can be used as a foundation for -building different shell UIs based on different graphics toolkits. - -## License - -You are free to get this code and use to build real GTK+ shell clients as you -wish. All you have to do is add the MIT license on your project, maintaining -the [copyright](https://github.com/tiagovignatti/gtk-shell/blob/master/LICENSE) in there. - -## More - -http://vignatti.wordpress.com/2013/03/05/ui-customization-on-wayland/ +License information can be found in the LICENSE file in the same +directory as this README. diff --git a/shell/clock.c b/shell/clock.c index 909ec90..afda643 100644 --- a/shell/clock.c +++ b/shell/clock.c @@ -35,6 +35,7 @@ static guint signals[N_SIGNALS] = { 0 }; struct MaynardClockPrivate { GtkWidget *revealer_clock; + GtkWidget *revealer_system; GtkWidget *revealer_volume; GtkWidget *label; @@ -141,6 +142,12 @@ volume_idle_cb (gpointer data) } static GtkWidget * +create_system_box (MaynardClock *self) +{ + return gtk_label_new ("Not implemented yet!"); +} + +static GtkWidget * create_volume_box (MaynardClock *self) { GtkWidget *box; @@ -242,7 +249,7 @@ static void maynard_clock_constructed (GObject *object) { MaynardClock *self = MAYNARD_CLOCK (object); - GtkWidget *box, *volume_box; + GtkWidget *box, *system_box, *volume_box; G_OBJECT_CLASS (maynard_clock_parent_class)->constructed (object); @@ -276,6 +283,20 @@ maynard_clock_constructed (GObject *object) gtk_container_add (GTK_CONTAINER (self->priv->revealer_volume), volume_box); + /* system */ + self->priv->revealer_system = gtk_revealer_new (); + gtk_revealer_set_transition_type ( + GTK_REVEALER (self->priv->revealer_system), + GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT); + gtk_revealer_set_reveal_child ( + GTK_REVEALER (self->priv->revealer_system), FALSE); + gtk_box_pack_start (GTK_BOX (box), self->priv->revealer_system, + TRUE, TRUE, 0); + + system_box = create_system_box (self); + gtk_container_add (GTK_CONTAINER (self->priv->revealer_system), + system_box); + /* clock */ self->priv->revealer_clock = gtk_revealer_new (); gtk_revealer_set_transition_type ( @@ -291,6 +312,10 @@ maynard_clock_constructed (GObject *object) gtk_container_add (GTK_CONTAINER (self->priv->revealer_clock), self->priv->label); + /* TODO: work out how to fix the padding properly. this is added to + * fix the broken alignment where the clock appears to the right. */ + gtk_box_pack_start (GTK_BOX (box), gtk_revealer_new (), TRUE, TRUE, 0); + setup_mixer (self); wall_clock_notify_cb (self->priv->wall_clock, NULL, self); @@ -334,11 +359,18 @@ maynard_clock_new (void) } void -maynard_clock_show_volume (MaynardClock *self, - gboolean value) +maynard_clock_show_section (MaynardClock *self, + MaynardClockSection section) { gtk_revealer_set_reveal_child ( - GTK_REVEALER (self->priv->revealer_volume), value); + GTK_REVEALER (self->priv->revealer_clock), + section == MAYNARD_CLOCK_SECTION_CLOCK); + + gtk_revealer_set_reveal_child ( + GTK_REVEALER (self->priv->revealer_system), + section == MAYNARD_CLOCK_SECTION_SYSTEM); + gtk_revealer_set_reveal_child ( - GTK_REVEALER (self->priv->revealer_clock), !value); + GTK_REVEALER (self->priv->revealer_volume), + section == MAYNARD_CLOCK_SECTION_VOLUME); } diff --git a/shell/clock.h b/shell/clock.h index a0803e8..8044a27 100644 --- a/shell/clock.h +++ b/shell/clock.h @@ -52,11 +52,16 @@ struct MaynardClockClass #define MAYNARD_CLOCK_WIDTH (MAYNARD_PANEL_WIDTH * 2.6) #define MAYNARD_CLOCK_HEIGHT (MAYNARD_PANEL_WIDTH * 2) +typedef enum { + MAYNARD_CLOCK_SECTION_CLOCK, + MAYNARD_CLOCK_SECTION_SYSTEM, + MAYNARD_CLOCK_SECTION_VOLUME +} MaynardClockSection; + GType maynard_clock_get_type (void) G_GNUC_CONST; GtkWidget * maynard_clock_new (void); -void maynard_clock_show_volume (MaynardClock *self, - gboolean value); +void maynard_clock_show_section (MaynardClock *self, MaynardClockSection section); #endif /* __MAYNARD_CLOCK_H__ */ diff --git a/shell/favorites.c b/shell/favorites.c index 45e4359..7f15e76 100644 --- a/shell/favorites.c +++ b/shell/favorites.c @@ -30,8 +30,10 @@ #include "app-icon.h" enum { - PROP_0, + APP_LAUNCHED, + N_SIGNALS }; +static guint signals[N_SIGNALS] = { 0 }; struct MaynardFavoritesPrivate { GSettings *settings; @@ -54,6 +56,8 @@ favorite_clicked (GtkButton *button, error->message); g_clear_error (&error); } + + g_signal_emit (self, signals[APP_LAUNCHED], 0); } static void @@ -140,6 +144,10 @@ maynard_favorites_class_init (MaynardFavoritesClass *klass) object_class->dispose = maynard_favorites_dispose; + signals[APP_LAUNCHED] = g_signal_new ("app-launched", + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, + NULL, G_TYPE_NONE, 0); + g_type_class_add_private (object_class, sizeof (MaynardFavoritesPrivate)); } diff --git a/shell/maynard.c b/shell/maynard.c index e5d60ea..d9c8f10 100644 --- a/shell/maynard.c +++ b/shell/maynard.c @@ -45,547 +45,616 @@ extern char **environ; /* defined by libc */ #define DEFAULT_BACKGROUND "/usr/share/wallpapers/Hanami/contents/images/3872x2592.jpg" struct element { - GtkWidget *window; - GdkPixbuf *pixbuf; - struct wl_surface *surface; + GtkWidget *window; + GdkPixbuf *pixbuf; + struct wl_surface *surface; }; struct desktop { - struct wl_display *display; - struct wl_registry *registry; - struct desktop_shell *shell; - struct wl_output *output; - struct shell_helper *helper; + struct wl_display *display; + struct wl_registry *registry; + struct desktop_shell *shell; + struct wl_output *output; + struct shell_helper *helper; - GdkDisplay *gdk_display; + GdkDisplay *gdk_display; - struct element *background; - struct element *panel; - struct element *launcher_grid; - struct element *clock; + struct element *background; + struct element *panel; + struct element *launcher_grid; + struct element *clock; - guint initial_panel_timeout_id; - guint hide_panel_idle_id; + guint initial_panel_timeout_id; + guint hide_panel_idle_id; - gboolean grid_visible; - gboolean volume_visible; + gboolean grid_visible; + gboolean system_visible; + gboolean volume_visible; }; static gboolean panel_window_enter_cb (GtkWidget *widget, - GdkEventCrossing *event, - struct desktop *desktop); + GdkEventCrossing *event, struct desktop *desktop); static gboolean panel_window_leave_cb (GtkWidget *widget, - GdkEventCrossing *event, - struct desktop *desktop); + GdkEventCrossing *event, struct desktop *desktop); static gboolean connect_enter_leave_signals (gpointer data) { - struct desktop *desktop = data; - GList *l; + struct desktop *desktop = data; + GList *l; - g_signal_connect (desktop->panel->window, "enter-notify-event", - G_CALLBACK (panel_window_enter_cb), desktop); - g_signal_connect (desktop->panel->window, "leave-notify-event", - G_CALLBACK (panel_window_leave_cb), desktop); + g_signal_connect (desktop->panel->window, "enter-notify-event", + G_CALLBACK (panel_window_enter_cb), desktop); + g_signal_connect (desktop->panel->window, "leave-notify-event", + G_CALLBACK (panel_window_leave_cb), desktop); - g_signal_connect (desktop->clock->window, "enter-notify-event", - G_CALLBACK (panel_window_enter_cb), desktop); - g_signal_connect (desktop->clock->window, "leave-notify-event", - G_CALLBACK (panel_window_leave_cb), desktop); + g_signal_connect (desktop->clock->window, "enter-notify-event", + G_CALLBACK (panel_window_enter_cb), desktop); + g_signal_connect (desktop->clock->window, "leave-notify-event", + G_CALLBACK (panel_window_leave_cb), desktop); - g_signal_connect (desktop->launcher_grid->window, "enter-notify-event", - G_CALLBACK (panel_window_enter_cb), desktop); - g_signal_connect (desktop->launcher_grid->window, "leave-notify-event", - G_CALLBACK (panel_window_leave_cb), desktop); + g_signal_connect (desktop->launcher_grid->window, "enter-notify-event", + G_CALLBACK (panel_window_enter_cb), desktop); + g_signal_connect (desktop->launcher_grid->window, "leave-notify-event", + G_CALLBACK (panel_window_leave_cb), desktop); - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static void -desktop_shell_configure(void *data, - struct desktop_shell *desktop_shell, - uint32_t edges, - struct wl_surface *surface, - int32_t width, int32_t height) +desktop_shell_configure (void *data, + struct desktop_shell *desktop_shell, + uint32_t edges, + struct wl_surface *surface, + int32_t width, int32_t height) { - struct desktop *desktop = data; - int window_height; - int grid_width, grid_height; + struct desktop *desktop = data; + int window_height; + int grid_width, grid_height; - gtk_widget_set_size_request (desktop->background->window, - width, height); + gtk_widget_set_size_request (desktop->background->window, + width, height); - /* TODO: make this height a little nicer */ - window_height = height * MAYNARD_PANEL_HEIGHT_RATIO; - gtk_window_resize (GTK_WINDOW (desktop->panel->window), - MAYNARD_PANEL_WIDTH, window_height); + /* TODO: make this height a little nicer */ + window_height = height * MAYNARD_PANEL_HEIGHT_RATIO; + gtk_window_resize (GTK_WINDOW (desktop->panel->window), + MAYNARD_PANEL_WIDTH, window_height); - maynard_launcher_calculate (MAYNARD_LAUNCHER(desktop->launcher_grid->window), - &grid_width, &grid_height, NULL); - gtk_widget_set_size_request (desktop->launcher_grid->window, - grid_width, - grid_height); + maynard_launcher_calculate (MAYNARD_LAUNCHER (desktop->launcher_grid->window), + &grid_width, &grid_height, NULL); + gtk_widget_set_size_request (desktop->launcher_grid->window, + grid_width, grid_height); - shell_helper_move_surface(desktop->helper, - desktop->panel->surface, - 0, (height - window_height) / 2); + shell_helper_move_surface (desktop->helper, desktop->panel->surface, + 0, (height - window_height) / 2); - gtk_window_resize (GTK_WINDOW (desktop->clock->window), - MAYNARD_CLOCK_WIDTH, - MAYNARD_CLOCK_HEIGHT); + gtk_window_resize (GTK_WINDOW (desktop->clock->window), + MAYNARD_CLOCK_WIDTH, MAYNARD_CLOCK_HEIGHT); - shell_helper_move_surface(desktop->helper, - desktop->clock->surface, - MAYNARD_PANEL_WIDTH, - (height - window_height) / 2); + shell_helper_move_surface (desktop->helper, desktop->clock->surface, + MAYNARD_PANEL_WIDTH, (height - window_height) / 2); - shell_helper_move_surface(desktop->helper, - desktop->launcher_grid->surface, - - grid_width, - ((height - window_height) / 2) + MAYNARD_CLOCK_HEIGHT); + shell_helper_move_surface (desktop->helper, + desktop->launcher_grid->surface, + - grid_width, + ((height - window_height) / 2) + MAYNARD_CLOCK_HEIGHT); - desktop_shell_desktop_ready(desktop->shell); + desktop_shell_desktop_ready (desktop->shell); - /* TODO: why does the panel signal leave on drawing for - * startup? we don't want to have to have this silly - * timeout. */ - g_timeout_add_seconds (1, connect_enter_leave_signals, desktop); + /* TODO: why does the panel signal leave on drawing for + * startup? we don't want to have to have this silly + * timeout. */ + g_timeout_add_seconds (1, connect_enter_leave_signals, desktop); } static void -desktop_shell_prepare_lock_surface(void *data, - struct desktop_shell *desktop_shell) +desktop_shell_prepare_lock_surface (void *data, + struct desktop_shell *desktop_shell) { - desktop_shell_unlock (desktop_shell); + desktop_shell_unlock (desktop_shell); } static void -desktop_shell_grab_cursor(void *data, struct desktop_shell *desktop_shell, - uint32_t cursor) +desktop_shell_grab_cursor (void *data, + struct desktop_shell *desktop_shell, + uint32_t cursor) { } static const struct desktop_shell_listener listener = { - desktop_shell_configure, - desktop_shell_prepare_lock_surface, - desktop_shell_grab_cursor + desktop_shell_configure, + desktop_shell_prepare_lock_surface, + desktop_shell_grab_cursor }; static void -launcher_grid_toggle (GtkWidget *widget, struct desktop *desktop) +launcher_grid_toggle (GtkWidget *widget, + struct desktop *desktop) { - if (desktop->grid_visible) { - shell_helper_slide_surface_back(desktop->helper, - desktop->launcher_grid->surface); - } else { - int width; + if (desktop->grid_visible) + { + shell_helper_slide_surface_back (desktop->helper, + desktop->launcher_grid->surface); + } + else + { + int width; - gtk_widget_get_size_request (desktop->launcher_grid->window, - &width, NULL); + gtk_widget_get_size_request (desktop->launcher_grid->window, + &width, NULL); - shell_helper_slide_surface(desktop->helper, - desktop->launcher_grid->surface, - width + MAYNARD_PANEL_WIDTH, 0); - } + shell_helper_slide_surface (desktop->helper, + desktop->launcher_grid->surface, + width + MAYNARD_PANEL_WIDTH, 0); + } - desktop->grid_visible = !desktop->grid_visible; + desktop->grid_visible = !desktop->grid_visible; } static void launcher_grid_create (struct desktop *desktop) { - struct element *launcher_grid; - GdkWindow *gdk_window; + struct element *launcher_grid; + GdkWindow *gdk_window; - launcher_grid = malloc (sizeof *launcher_grid); - memset (launcher_grid, 0, sizeof *launcher_grid); + launcher_grid = malloc (sizeof *launcher_grid); + memset (launcher_grid, 0, sizeof *launcher_grid); - launcher_grid->window = maynard_launcher_new (desktop->background->window); - gdk_window = gtk_widget_get_window(launcher_grid->window); - launcher_grid->surface = gdk_wayland_window_get_wl_surface(gdk_window); + launcher_grid->window = maynard_launcher_new (desktop->background->window); + gdk_window = gtk_widget_get_window (launcher_grid->window); + launcher_grid->surface = gdk_wayland_window_get_wl_surface (gdk_window); - gdk_wayland_window_set_use_custom_surface(gdk_window); - shell_helper_add_surface_to_layer(desktop->helper, - launcher_grid->surface, - desktop->panel->surface); + gdk_wayland_window_set_use_custom_surface (gdk_window); + shell_helper_add_surface_to_layer (desktop->helper, + launcher_grid->surface, + desktop->panel->surface); - g_signal_connect(launcher_grid->window, "app-launched", - G_CALLBACK(launcher_grid_toggle), desktop); + g_signal_connect (launcher_grid->window, "app-launched", + G_CALLBACK (launcher_grid_toggle), desktop); - gtk_widget_show_all(launcher_grid->window); + gtk_widget_show_all (launcher_grid->window); - desktop->launcher_grid = launcher_grid; + desktop->launcher_grid = launcher_grid; } static void volume_changed_cb (MaynardClock *clock, - gdouble value, - const gchar *icon_name, - struct desktop *desktop) + gdouble value, + const gchar *icon_name, + struct desktop *desktop) { - maynard_panel_set_volume_icon_name ( - MAYNARD_PANEL (desktop->panel->window), icon_name); + maynard_panel_set_volume_icon_name ( + MAYNARD_PANEL (desktop->panel->window), icon_name); } static GtkWidget * clock_create (struct desktop *desktop) { - struct element *clock; - GdkWindow *gdk_window; + struct element *clock; + GdkWindow *gdk_window; - clock = malloc(sizeof *clock); - memset(clock, 0, sizeof *clock); + clock = malloc (sizeof *clock); + memset (clock, 0, sizeof *clock); - clock->window = maynard_clock_new(); + clock->window = maynard_clock_new (); - g_signal_connect (clock->window, "volume-changed", - G_CALLBACK (volume_changed_cb), desktop); + g_signal_connect (clock->window, "volume-changed", + G_CALLBACK (volume_changed_cb), desktop); - gdk_window = gtk_widget_get_window(clock->window); - clock->surface = gdk_wayland_window_get_wl_surface(gdk_window); + gdk_window = gtk_widget_get_window (clock->window); + clock->surface = gdk_wayland_window_get_wl_surface (gdk_window); - gdk_wayland_window_set_use_custom_surface(gdk_window); - shell_helper_add_surface_to_layer(desktop->helper, clock->surface, - desktop->panel->surface); + gdk_wayland_window_set_use_custom_surface (gdk_window); + shell_helper_add_surface_to_layer (desktop->helper, clock->surface, + desktop->panel->surface); - gtk_widget_show_all (clock->window); + gtk_widget_show_all (clock->window); - desktop->clock = clock; + desktop->clock = clock; } static void -volume_toggled_cb (GtkWidget *widget, - struct desktop *desktop) +button_toggled_cb (struct desktop *desktop, + gboolean *visible, + gboolean *not_visible) +{ + *visible = !*visible; + *not_visible = FALSE; + + if (desktop->system_visible) + { + maynard_clock_show_section (MAYNARD_CLOCK (desktop->clock->window), + MAYNARD_CLOCK_SECTION_SYSTEM); + maynard_panel_show_previous (MAYNARD_PANEL (desktop->panel->window), + MAYNARD_PANEL_BUTTON_SYSTEM); + } + else if (desktop->volume_visible) + { + maynard_clock_show_section (MAYNARD_CLOCK (desktop->clock->window), + MAYNARD_CLOCK_SECTION_VOLUME); + maynard_panel_show_previous (MAYNARD_PANEL (desktop->panel->window), + MAYNARD_PANEL_BUTTON_VOLUME); + } + else + { + maynard_clock_show_section (MAYNARD_CLOCK (desktop->clock->window), + MAYNARD_CLOCK_SECTION_CLOCK); + maynard_panel_show_previous (MAYNARD_PANEL (desktop->panel->window), + MAYNARD_PANEL_BUTTON_NONE); + } +} + +static void +system_toggled_cb (GtkWidget *widget, + struct desktop *desktop) { - desktop->volume_visible = !desktop->volume_visible; + button_toggled_cb (desktop, + &desktop->system_visible, + &desktop->volume_visible); +} - maynard_clock_show_volume (MAYNARD_CLOCK (desktop->clock->window), - desktop->volume_visible); - maynard_panel_show_volume_previous (MAYNARD_PANEL (desktop->panel->window), - desktop->volume_visible); +static void +volume_toggled_cb (GtkWidget *widget, + struct desktop *desktop) +{ + button_toggled_cb (desktop, + &desktop->volume_visible, + &desktop->system_visible); } static gboolean panel_window_enter_cb (GtkWidget *widget, - GdkEventCrossing *event, - struct desktop *desktop) + GdkEventCrossing *event, + struct desktop *desktop) { - if (desktop->initial_panel_timeout_id > 0) { - g_source_remove (desktop->initial_panel_timeout_id); - desktop->initial_panel_timeout_id = 0; - } + if (desktop->initial_panel_timeout_id > 0) + { + g_source_remove (desktop->initial_panel_timeout_id); + desktop->initial_panel_timeout_id = 0; + } - if (desktop->hide_panel_idle_id > 0) { - g_source_remove (desktop->hide_panel_idle_id); - desktop->hide_panel_idle_id = 0; - return; - } + if (desktop->hide_panel_idle_id > 0) + { + g_source_remove (desktop->hide_panel_idle_id); + desktop->hide_panel_idle_id = 0; + return; + } - shell_helper_slide_surface_back(desktop->helper, - desktop->panel->surface); - shell_helper_slide_surface_back(desktop->helper, - desktop->clock->surface); + shell_helper_slide_surface_back (desktop->helper, + desktop->panel->surface); + shell_helper_slide_surface_back (desktop->helper, + desktop->clock->surface); - maynard_panel_set_expand(MAYNARD_PANEL(desktop->panel->window), - TRUE); + maynard_panel_set_expand (MAYNARD_PANEL (desktop->panel->window), TRUE); - return FALSE; + return FALSE; } static gboolean leave_panel_idle_cb (gpointer data) { - struct desktop *desktop = data; - gint width; + struct desktop *desktop = data; + gint width; - desktop->hide_panel_idle_id = 0; + desktop->hide_panel_idle_id = 0; - gtk_window_get_size (GTK_WINDOW (desktop->clock->window), - &width, NULL); + gtk_window_get_size (GTK_WINDOW (desktop->clock->window), + &width, NULL); - shell_helper_slide_surface(desktop->helper, - desktop->panel->surface, - MAYNARD_VERTICAL_CLOCK_WIDTH - MAYNARD_PANEL_WIDTH, 0); - shell_helper_slide_surface(desktop->helper, - desktop->clock->surface, - MAYNARD_VERTICAL_CLOCK_WIDTH - MAYNARD_PANEL_WIDTH - width, 0); + shell_helper_slide_surface (desktop->helper, + desktop->panel->surface, + MAYNARD_VERTICAL_CLOCK_WIDTH - MAYNARD_PANEL_WIDTH, 0); + shell_helper_slide_surface (desktop->helper, + desktop->clock->surface, + MAYNARD_VERTICAL_CLOCK_WIDTH - MAYNARD_PANEL_WIDTH - width, 0); - maynard_panel_set_expand(MAYNARD_PANEL(desktop->panel->window), - FALSE); + maynard_panel_set_expand (MAYNARD_PANEL (desktop->panel->window), FALSE); - maynard_clock_show_volume (MAYNARD_CLOCK (desktop->clock->window), FALSE); - maynard_panel_show_volume_previous (MAYNARD_PANEL (desktop->panel->window), FALSE); - desktop->volume_visible = FALSE; + maynard_clock_show_section (MAYNARD_CLOCK (desktop->clock->window), + MAYNARD_CLOCK_SECTION_CLOCK); + maynard_panel_show_previous (MAYNARD_PANEL (desktop->panel->window), + MAYNARD_PANEL_BUTTON_NONE); + desktop->system_visible = FALSE; + desktop->volume_visible = FALSE; - return G_SOURCE_REMOVE; + return G_SOURCE_REMOVE; } static gboolean panel_window_leave_cb (GtkWidget *widget, - GdkEventCrossing *event, - struct desktop *desktop) + GdkEventCrossing *event, + struct desktop *desktop) { - if (desktop->initial_panel_timeout_id > 0) { - g_source_remove (desktop->initial_panel_timeout_id); - desktop->initial_panel_timeout_id = 0; - } + if (desktop->initial_panel_timeout_id > 0) + { + g_source_remove (desktop->initial_panel_timeout_id); + desktop->initial_panel_timeout_id = 0; + } - if (desktop->hide_panel_idle_id > 0) - return; + if (desktop->hide_panel_idle_id > 0) + return; - if (desktop->grid_visible) - return; + if (desktop->grid_visible) + return; - desktop->hide_panel_idle_id = g_idle_add (leave_panel_idle_cb, desktop); + desktop->hide_panel_idle_id = g_idle_add (leave_panel_idle_cb, desktop); - return FALSE; + return FALSE; } static gboolean panel_hide_timeout_cb (gpointer data) { - struct desktop *desktop = data; + struct desktop *desktop = data; + + panel_window_leave_cb (NULL, NULL, desktop); + + return G_SOURCE_REMOVE; +} - panel_window_leave_cb (NULL, NULL, desktop); +static void +favorite_launched_cb (MaynardPanel *panel, + struct desktop *desktop) +{ + if (desktop->grid_visible) + launcher_grid_toggle (desktop->launcher_grid->window, desktop); - return G_SOURCE_REMOVE; + panel_window_leave_cb (NULL, NULL, desktop); } static void -panel_create(struct desktop *desktop) +panel_create (struct desktop *desktop) { - struct element *panel; - GdkWindow *gdk_window; + struct element *panel; + GdkWindow *gdk_window; - panel = malloc(sizeof *panel); - memset(panel, 0, sizeof *panel); + panel = malloc (sizeof *panel); + memset (panel, 0, sizeof *panel); - panel->window = maynard_panel_new(); + panel->window = maynard_panel_new (); - g_signal_connect(panel->window, "app-menu-toggled", - G_CALLBACK(launcher_grid_toggle), desktop); - g_signal_connect(panel->window, "volume-toggled", - G_CALLBACK(volume_toggled_cb), desktop); + g_signal_connect (panel->window, "app-menu-toggled", + G_CALLBACK (launcher_grid_toggle), desktop); + g_signal_connect (panel->window, "system-toggled", + G_CALLBACK (system_toggled_cb), desktop); + g_signal_connect (panel->window, "volume-toggled", + G_CALLBACK (volume_toggled_cb), desktop); + g_signal_connect (panel->window, "favorite-launched", + G_CALLBACK (favorite_launched_cb), desktop); - desktop->initial_panel_timeout_id = - g_timeout_add_seconds(2, panel_hide_timeout_cb, desktop); + desktop->initial_panel_timeout_id = + g_timeout_add_seconds (2, panel_hide_timeout_cb, desktop); - /* set it up as the panel */ - gdk_window = gtk_widget_get_window(panel->window); - gdk_wayland_window_set_use_custom_surface(gdk_window); + /* set it up as the panel */ + gdk_window = gtk_widget_get_window (panel->window); + gdk_wayland_window_set_use_custom_surface (gdk_window); - panel->surface = gdk_wayland_window_get_wl_surface(gdk_window); - desktop_shell_set_user_data(desktop->shell, desktop); - desktop_shell_set_panel(desktop->shell, desktop->output, - panel->surface); - desktop_shell_set_panel_position(desktop->shell, - DESKTOP_SHELL_PANEL_POSITION_LEFT); + panel->surface = gdk_wayland_window_get_wl_surface (gdk_window); + desktop_shell_set_user_data (desktop->shell, desktop); + desktop_shell_set_panel (desktop->shell, desktop->output, panel->surface); + desktop_shell_set_panel_position (desktop->shell, + DESKTOP_SHELL_PANEL_POSITION_LEFT); - gtk_widget_show_all(panel->window); + gtk_widget_show_all (panel->window); - desktop->panel = panel; + desktop->panel = panel; } /* Expose callback for the drawing area */ static gboolean -draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data) +draw_cb (GtkWidget *widget, + cairo_t *cr, + gpointer data) { - struct desktop *desktop = data; + struct desktop *desktop = data; - gdk_cairo_set_source_pixbuf (cr, desktop->background->pixbuf, 0, 0); - cairo_paint (cr); + gdk_cairo_set_source_pixbuf (cr, desktop->background->pixbuf, 0, 0); + cairo_paint (cr); - return TRUE; + return TRUE; } /* Destroy handler for the window */ static void -destroy_cb (GObject *object, gpointer data) +destroy_cb (GObject *object, + gpointer data) { - gtk_main_quit (); + gtk_main_quit (); } static GdkPixbuf * scale_background (GdkPixbuf *original_pixbuf) { - /* Scale original_pixbuf so it mostly fits on the screen. - * If the aspect ratio is different than a bit on the right or on the - * bottom could be cropped out. */ - GdkScreen *screen = gdk_screen_get_default (); - gint screen_width, screen_height; - gint original_width, original_height; - gint final_width, final_height; - gdouble ratio_horizontal, ratio_vertical, ratio; + /* Scale original_pixbuf so it mostly fits on the screen. + * If the aspect ratio is different than a bit on the right or on the + * bottom could be cropped out. */ + GdkScreen *screen = gdk_screen_get_default (); + gint screen_width, screen_height; + gint original_width, original_height; + gint final_width, final_height; + gdouble ratio_horizontal, ratio_vertical, ratio; - screen_width = gdk_screen_get_width (screen); - screen_height = gdk_screen_get_height (screen); - original_width = gdk_pixbuf_get_width (original_pixbuf); - original_height = gdk_pixbuf_get_height (original_pixbuf); + screen_width = gdk_screen_get_width (screen); + screen_height = gdk_screen_get_height (screen); + original_width = gdk_pixbuf_get_width (original_pixbuf); + original_height = gdk_pixbuf_get_height (original_pixbuf); - ratio_horizontal = (double) screen_width / original_width; - ratio_vertical = (double) screen_height / original_height; - ratio = MAX (ratio_horizontal, ratio_vertical); + ratio_horizontal = (double) screen_width / original_width; + ratio_vertical = (double) screen_height / original_height; + ratio = MAX (ratio_horizontal, ratio_vertical); - final_width = ceil (ratio * original_width); - final_height = ceil (ratio * original_height); + final_width = ceil (ratio * original_width); + final_height = ceil (ratio * original_height); - return gdk_pixbuf_scale_simple (original_pixbuf, - final_width, final_height, GDK_INTERP_BILINEAR); + return gdk_pixbuf_scale_simple (original_pixbuf, + final_width, final_height, GDK_INTERP_BILINEAR); } static void -background_create(struct desktop *desktop) +background_create (struct desktop *desktop) { - GdkWindow *gdk_window; - struct element *background; - const gchar *filename; - GdkPixbuf *unscaled_background; + GdkWindow *gdk_window; + struct element *background; + const gchar *filename; + GdkPixbuf *unscaled_background; - background = malloc(sizeof *background); - memset(background, 0, sizeof *background); + background = malloc (sizeof *background); + memset (background, 0, sizeof *background); - filename = g_getenv("BACKGROUND"); - if (filename == NULL) - filename = DEFAULT_BACKGROUND; - unscaled_background = gdk_pixbuf_new_from_file (filename, NULL); - if (!unscaled_background) { - g_message ("Could not load background. " - "Do you have kdewallpapers installed?"); - exit (EXIT_FAILURE); - } + filename = g_getenv ("BACKGROUND"); + if (filename == NULL) + filename = DEFAULT_BACKGROUND; + unscaled_background = gdk_pixbuf_new_from_file (filename, NULL); + if (!unscaled_background) + { + g_message ("Could not load background. " + "Do you have kdewallpapers installed?"); + exit (EXIT_FAILURE); + } - background->pixbuf = scale_background (unscaled_background); - g_object_unref (unscaled_background); + background->pixbuf = scale_background (unscaled_background); + g_object_unref (unscaled_background); - background->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + background->window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - g_signal_connect (background->window, "destroy", - G_CALLBACK (destroy_cb), NULL); + g_signal_connect (background->window, "destroy", + G_CALLBACK (destroy_cb), NULL); - g_signal_connect (background->window, "draw", - G_CALLBACK (draw_cb), desktop); + g_signal_connect (background->window, "draw", + G_CALLBACK (draw_cb), desktop); - gtk_window_set_title(GTK_WINDOW(background->window), "maynard"); - gtk_window_set_decorated(GTK_WINDOW(background->window), FALSE); - gtk_widget_realize(background->window); + gtk_window_set_title (GTK_WINDOW (background->window), "maynard"); + gtk_window_set_decorated (GTK_WINDOW (background->window), FALSE); + gtk_widget_realize (background->window); - gdk_window = gtk_widget_get_window(background->window); - gdk_wayland_window_set_use_custom_surface(gdk_window); + gdk_window = gtk_widget_get_window (background->window); + gdk_wayland_window_set_use_custom_surface (gdk_window); - background->surface = gdk_wayland_window_get_wl_surface(gdk_window); - desktop_shell_set_user_data(desktop->shell, desktop); - desktop_shell_set_background(desktop->shell, desktop->output, - background->surface); + background->surface = gdk_wayland_window_get_wl_surface (gdk_window); + desktop_shell_set_user_data (desktop->shell, desktop); + desktop_shell_set_background (desktop->shell, desktop->output, + background->surface); - desktop->background = background; + desktop->background = background; - gtk_widget_show_all(background->window); + gtk_widget_show_all (background->window); } static void -css_setup(struct desktop *desktop) +css_setup (struct desktop *desktop) { - GtkCssProvider *provider; - GFile *file; - GError *error = NULL; + GtkCssProvider *provider; + GFile *file; + GError *error = NULL; - provider = gtk_css_provider_new (); + provider = gtk_css_provider_new (); - file = g_file_new_for_uri ("resource:///org/raspberry-pi/maynard/style.css"); + file = g_file_new_for_uri ("resource:///org/raspberry-pi/maynard/style.css"); - if (!gtk_css_provider_load_from_file (provider, file, &error)) { - g_warning ("Failed to load CSS file: %s", error->message); - g_clear_error (&error); - g_object_unref (file); - return; - } + if (!gtk_css_provider_load_from_file (provider, file, &error)) + { + g_warning ("Failed to load CSS file: %s", error->message); + g_clear_error (&error); + g_object_unref (file); + return; + } - gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), - GTK_STYLE_PROVIDER (provider), 600); + gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), + GTK_STYLE_PROVIDER (provider), 600); - g_object_unref (file); + g_object_unref (file); } static void -registry_handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) +registry_handle_global (void *data, + struct wl_registry *registry, + uint32_t name, + const char *interface, + uint32_t version) { - struct desktop *d = data; - - if (!strcmp(interface, "desktop_shell")) { - d->shell = wl_registry_bind(registry, name, - &desktop_shell_interface, 3); - desktop_shell_add_listener(d->shell, &listener, d); - } else if (!strcmp(interface, "wl_output")) { + struct desktop *d = data; - /* TODO: create multiple outputs */ - d->output = wl_registry_bind(registry, name, - &wl_output_interface, 1); - } else if (!strcmp(interface, "shell_helper")) { - d->helper = wl_registry_bind(registry, name, - &shell_helper_interface, 1); - } + if (!strcmp (interface, "desktop_shell")) + { + d->shell = wl_registry_bind (registry, name, + &desktop_shell_interface, 3); + desktop_shell_add_listener (d->shell, &listener, d); + } + else if (!strcmp (interface, "wl_output")) + { + /* TODO: create multiple outputs */ + d->output = wl_registry_bind (registry, name, + &wl_output_interface, 1); + } + else if (!strcmp (interface, "shell_helper")) + { + d->helper = wl_registry_bind (registry, name, + &shell_helper_interface, 1); + } } static void -registry_handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) +registry_handle_global_remove (void *data, + struct wl_registry *registry, + uint32_t name) { } static const struct wl_registry_listener registry_listener = { - registry_handle_global, - registry_handle_global_remove + registry_handle_global, + registry_handle_global_remove }; int -main(int argc, char *argv[]) +main (int argc, + char *argv[]) { - struct desktop *desktop; + struct desktop *desktop; - gdk_set_allowed_backends ("wayland"); + gdk_set_allowed_backends ("wayland"); - gtk_init(&argc, &argv); + gtk_init (&argc, &argv); - g_resources_register (maynard_get_resource ()); + g_resources_register (maynard_get_resource ()); - desktop = malloc(sizeof *desktop); - desktop->output = NULL; - desktop->shell = NULL; - desktop->helper = NULL; + desktop = malloc (sizeof *desktop); + desktop->output = NULL; + desktop->shell = NULL; + desktop->helper = NULL; - desktop->gdk_display = gdk_display_get_default(); - desktop->display = - gdk_wayland_display_get_wl_display(desktop->gdk_display); - if (desktop->display == NULL) { - fprintf(stderr, "failed to get display: %m\n"); - return -1; - } + desktop->gdk_display = gdk_display_get_default (); + desktop->display = + gdk_wayland_display_get_wl_display (desktop->gdk_display); + if (desktop->display == NULL) + { + fprintf (stderr, "failed to get display: %m\n"); + return -1; + } - desktop->registry = wl_display_get_registry(desktop->display); - wl_registry_add_listener(desktop->registry, - ®istry_listener, desktop); + desktop->registry = wl_display_get_registry (desktop->display); + wl_registry_add_listener (desktop->registry, + ®istry_listener, desktop); - /* Wait until we have been notified about the compositor, - * shell, and shell helper objects */ - while (!desktop->output || !desktop->shell || !desktop->helper) - wl_display_roundtrip (desktop->display); + /* Wait until we have been notified about the compositor, + * shell, and shell helper objects */ + while (!desktop->output || !desktop->shell || !desktop->helper) + wl_display_roundtrip (desktop->display); - desktop->grid_visible = FALSE; - desktop->volume_visible = FALSE; + desktop->grid_visible = FALSE; + desktop->system_visible = FALSE; + desktop->volume_visible = FALSE; - css_setup(desktop); - background_create(desktop); + css_setup (desktop); + background_create (desktop); - /* panel needs to be first so the clock and launcher grid can - * be added to its layer */ - panel_create(desktop); - clock_create(desktop); - launcher_grid_create (desktop); + /* panel needs to be first so the clock and launcher grid can + * be added to its layer */ + panel_create (desktop); + clock_create (desktop); + launcher_grid_create (desktop); - gtk_main(); + gtk_main (); - /* TODO cleanup */ - return EXIT_SUCCESS; + /* TODO cleanup */ + return EXIT_SUCCESS; } diff --git a/shell/panel.c b/shell/panel.c index 7324c71..74ab751 100644 --- a/shell/panel.c +++ b/shell/panel.c @@ -29,7 +29,9 @@ enum { APP_MENU_TOGGLED, + SYSTEM_TOGGLED, VOLUME_TOGGLED, + FAVORITE_LAUNCHED, N_SIGNALS }; static guint signals[N_SIGNALS] = { 0 }; @@ -40,6 +42,8 @@ struct MaynardPanelPrivate { GtkWidget *revealer_buttons; /* for the top buttons */ GtkWidget *revealer_clock; /* for the vertical clock */ + GtkWidget *system_button; + gboolean volume_showing; GtkWidget *volume_button; gchar *volume_icon_name; @@ -83,6 +87,13 @@ app_menu_button_clicked_cb (GtkButton *button, } static void +system_button_clicked_cb (GtkButton *button, + MaynardPanel *self) +{ + g_signal_emit (self, signals[SYSTEM_TOGGLED], 0); +} + +static void volume_button_clicked_cb (GtkButton *button, MaynardPanel *self) { @@ -90,6 +101,13 @@ volume_button_clicked_cb (GtkButton *button, } static void +favorite_launched_cb (MaynardFavorites *favorites, + MaynardPanel *self) +{ + g_signal_emit (self, signals[FAVORITE_LAUNCHED], 0); +} + +static void maynard_panel_constructed (GObject *object) { MaynardPanel *self = MAYNARD_PANEL (object); @@ -97,6 +115,7 @@ maynard_panel_constructed (GObject *object) GtkWidget *ebox; GtkWidget *image; GtkWidget *button; + GtkWidget *favorites; G_OBJECT_CLASS (maynard_panel_parent_class)->constructed (object); @@ -147,15 +166,25 @@ maynard_panel_constructed (GObject *object) gtk_container_add (GTK_CONTAINER (self->priv->revealer_buttons), buttons_box); /* system button */ - image = gtk_image_new_from_icon_name ("emblem-system-symbolic", + ebox = gtk_event_box_new (); + gtk_box_pack_start (GTK_BOX (buttons_box), ebox, FALSE, FALSE, 0); + button = gtk_button_new_from_icon_name ("emblem-system-symbolic", GTK_ICON_SIZE_LARGE_TOOLBAR); - gtk_style_context_add_class (gtk_widget_get_style_context (image), + gtk_style_context_add_class (gtk_widget_get_style_context (button), "maynard-system"); - gtk_box_pack_start (GTK_BOX (buttons_box), image, FALSE, FALSE, 0); + gtk_style_context_remove_class (gtk_widget_get_style_context (button), + "button"); + gtk_style_context_remove_class (gtk_widget_get_style_context (button), + "image-button"); + g_signal_connect (button, "clicked", + G_CALLBACK (system_button_clicked_cb), self); + gtk_container_add (GTK_CONTAINER (ebox), button); + widget_connect_enter_signal (self, ebox); + self->priv->system_button = button; /* sound button */ ebox = gtk_event_box_new (); - gtk_box_pack_end (GTK_BOX (buttons_box), ebox, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (buttons_box), ebox, FALSE, FALSE, 0); button = gtk_button_new_from_icon_name (self->priv->volume_icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR); gtk_style_context_add_class (gtk_widget_get_style_context (button), @@ -188,9 +217,13 @@ maynard_panel_constructed (GObject *object) /* favorites */ ebox = gtk_event_box_new (); gtk_box_pack_start (GTK_BOX (main_box), ebox, FALSE, FALSE, 0); - gtk_container_add (GTK_CONTAINER (ebox), maynard_favorites_new ()); + favorites = maynard_favorites_new (); + gtk_container_add (GTK_CONTAINER (ebox), favorites); widget_connect_enter_signal (self, ebox); + g_signal_connect (favorites, "app-launched", + G_CALLBACK (favorite_launched_cb), self); + /* bottom app menu button */ ebox = gtk_event_box_new (); gtk_box_pack_end (GTK_BOX (main_box), ebox, FALSE, FALSE, 0); @@ -229,10 +262,18 @@ maynard_panel_class_init (MaynardPanelClass *klass) G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + signals[SYSTEM_TOGGLED] = g_signal_new ("system-toggled", + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, + NULL, G_TYPE_NONE, 0); + signals[VOLUME_TOGGLED] = g_signal_new ("volume-toggled", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + signals[FAVORITE_LAUNCHED] = g_signal_new ("favorite-launched", + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, + NULL, G_TYPE_NONE, 0); + g_type_class_add_private (object_class, sizeof (MaynardPanelPrivate)); } @@ -252,29 +293,39 @@ maynard_panel_set_expand (MaynardPanel *self, } static void -set_volume_icon (MaynardPanel *self, +set_icon (GtkWidget *button, const gchar *icon_name) { GtkWidget *image; image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR); - gtk_button_set_image (GTK_BUTTON (self->priv->volume_button), + gtk_button_set_image (GTK_BUTTON (button), image); } void -maynard_panel_show_volume_previous (MaynardPanel *self, - gboolean status) +maynard_panel_show_previous (MaynardPanel *self, + MaynardPanelButton button) { - const gchar *icon_name = self->priv->volume_icon_name; - - if (status) - icon_name = "go-previous-symbolic"; - - self->priv->volume_showing = !status; - - set_volume_icon (self, icon_name); + switch (button) + { + case MAYNARD_PANEL_BUTTON_SYSTEM: + set_icon (self->priv->system_button, "go-previous-symbolic"); + set_icon (self->priv->volume_button, self->priv->volume_icon_name); + self->priv->volume_showing = FALSE; + break; + case MAYNARD_PANEL_BUTTON_VOLUME: + set_icon (self->priv->system_button, "emblem-system-symbolic"); + set_icon (self->priv->volume_button, "go-previous-symbolic"); + self->priv->volume_showing = TRUE; + break; + case MAYNARD_PANEL_BUTTON_NONE: + default: + set_icon (self->priv->system_button, "emblem-system-symbolic"); + set_icon (self->priv->volume_button, self->priv->volume_icon_name); + self->priv->volume_showing = FALSE; + } } void @@ -285,5 +336,5 @@ maynard_panel_set_volume_icon_name (MaynardPanel *self, self->priv->volume_icon_name = g_strdup (icon_name); if (self->priv->volume_showing) - set_volume_icon (self, icon_name); + set_icon (self->priv->volume_button, icon_name); } diff --git a/shell/panel.h b/shell/panel.h index 5278e89..957fd9d 100644 --- a/shell/panel.h +++ b/shell/panel.h @@ -50,13 +50,19 @@ struct MaynardPanelClass #define MAYNARD_PANEL_WIDTH 56 #define MAYNARD_PANEL_HEIGHT_RATIO 0.73 +typedef enum { + MAYNARD_PANEL_BUTTON_NONE, + MAYNARD_PANEL_BUTTON_SYSTEM, + MAYNARD_PANEL_BUTTON_VOLUME +} MaynardPanelButton; + GType maynard_panel_get_type (void) G_GNUC_CONST; GtkWidget * maynard_panel_new (void); void maynard_panel_set_expand (MaynardPanel *self, gboolean expand); -void maynard_panel_show_volume_previous (MaynardPanel *self, gboolean status); +void maynard_panel_show_previous (MaynardPanel *self, MaynardPanelButton button); void maynard_panel_set_volume_icon_name (MaynardPanel *self, const gchar *icon_name); diff --git a/shell/style.css b/shell/style.css index e63580d..b2078bc 100644 --- a/shell/style.css +++ b/shell/style.css @@ -5,7 +5,7 @@ .maynard-system { background-color: #6d6d6d; color: white; - padding: 16px; + padding: 13px; } .maynard-audio { |
