Enhancement: Refactor Start menu, removes some hacks, fixes some bugs

This commit is contained in:
Rory Fewell
2024-02-25 21:20:12 +00:00
parent 977df806a5
commit 59dff93fc5
46 changed files with 3005 additions and 2075 deletions

View File

@@ -35,6 +35,8 @@ add_library(
libwintc-comgtk
src/assets.h
src/debug.h
src/container.c
src/container.h
src/defprocs.c
src/defprocs.h
src/errors.c

View File

@@ -9,6 +9,13 @@
//
#define WINTC_ASSETS_DIR "@CMAKE_INSTALL_PREFIX@/@WINTC_ASSETS_INSTALL_DIR@"
//
// Container-related
//
void wintc_gtk_container_clear(
GtkContainer* container
);
//
// Debugging
//

View File

@@ -0,0 +1,24 @@
#include <glib.h>
#include <gtk/gtk.h>
#include "container.h"
//
// PUBLIC FUNCTIONS
//
void wintc_gtk_container_clear(
GtkContainer* container
)
{
GList* children = gtk_container_get_children(container);
GList* iter = children;
while (iter)
{
gtk_widget_destroy(GTK_WIDGET(iter->data));
iter = iter->next;
}
g_list_free(children);
}

View File

@@ -0,0 +1,13 @@
#ifndef __CONTAINER_H__
#define __CONTAINER_H__
#include <gtk/gtk.h>
//
// PUBLIC FUNCTIONS
//
void wintc_gtk_container_clear(
GtkContainer* container
);
#endif

View File

@@ -20,7 +20,8 @@ typedef enum
// PUBLIC FUNCTIONS
//
GtkWidget* wintc_dpa_create_popup(
GtkWidget* owner
GtkWidget* owner,
gboolean enable_composition
);
void wintc_dpa_show_popup(
GtkWidget* popup,

View File

@@ -64,7 +64,8 @@ static gboolean on_popup_window_focus_out(
// PUBLIC FUNCTIONS
//
GtkWidget* wintc_dpa_create_popup(
GtkWidget* owner
GtkWidget* owner,
gboolean enable_composition
)
{
GtkWidget* popup;
@@ -77,10 +78,6 @@ GtkWidget* wintc_dpa_create_popup(
{
popup = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_decorated(
GTK_WINDOW(popup),
FALSE
);
gtk_window_set_type_hint(
GTK_WINDOW(popup),
GDK_WINDOW_TYPE_HINT_POPUP_MENU
@@ -106,6 +103,34 @@ GtkWidget* wintc_dpa_create_popup(
GDK_FOCUS_CHANGE_MASK
);
// If the application wants composition (eg. for shadows) we fake out
// CSD here
//
if (enable_composition)
{
GtkWidget* fake_titlebar = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
// HACK: Apply CSS to force the fake titlebar to not show up as
// Adwaita has a min-height on titlebar boxes! Blah!
//
wintc_widget_add_css(
fake_titlebar,
"* { min-height: 0px; }"
);
gtk_window_set_titlebar(
GTK_WINDOW(popup),
fake_titlebar
);
}
else
{
gtk_window_set_decorated(
GTK_WINDOW(popup),
FALSE
);
}
// Connect signals
//
g_signal_connect(
@@ -144,7 +169,11 @@ void wintc_dpa_show_popup(
);
gtk_widget_show_all(popup);
height = gtk_widget_get_allocated_height(popup);
gtk_window_get_size(
GTK_WINDOW(popup),
NULL,
&height
);
gdk_window_get_origin(
gtk_widget_get_window(owner),

View File

@@ -24,7 +24,8 @@ typedef enum
// PUBLIC FUNCTIONS
//
GtkWidget* wintc_dpa_create_popup(
GtkWidget* owner
GtkWidget* owner,
gboolean enable_composition
);
void wintc_dpa_show_popup(
GtkWidget* popup,

View File

@@ -6,9 +6,6 @@
#include "api.h"
#include "impl-x11.h"
// FIXME: Remove this before release
#define TASKBAND_ROW_HEIGHT 30
//
// STRUCTURE DEFINITIONS
//
@@ -127,12 +124,13 @@ static void on_taskband_realized(
)
{
GdkAtom cardinal_atom;
GdkDisplay* display = gdk_display_get_default();
GdkDisplay* display = gdk_display_get_default();
GdkRectangle geometry;
GdkMonitor* monitor = NULL;
int monitor_count = gdk_display_get_n_monitors(display);
gint height_request = 0;
GdkMonitor* monitor = NULL;
int monitor_count = gdk_display_get_n_monitors(display);
GdkAtom net_wm_strut_partial_atom;
int screen_bottom = 0;
int screen_bottom = 0;
cardinal_atom =
gdk_atom_intern_static_string("CARDINAL");
@@ -165,19 +163,25 @@ static void on_taskband_realized(
gdk_monitor_get_geometry(monitor, &geometry);
gtk_window_set_default_size(
GTK_WINDOW(self),
gtk_widget_get_size_request(
self,
NULL,
&height_request
);
gtk_widget_set_size_request(
self,
geometry.width,
TASKBAND_ROW_HEIGHT
height_request
);
gtk_window_move(
GTK_WINDOW(self),
geometry.x,
geometry.y + geometry.height - TASKBAND_ROW_HEIGHT
geometry.y + geometry.height - height_request
);
struts.bottom =
screen_bottom - (geometry.y + geometry.height) + TASKBAND_ROW_HEIGHT;
screen_bottom - (geometry.y + geometry.height) + height_request;
struts.bottom_start_x = geometry.x;
struts.bottom_end_x = geometry.x + geometry.width;

View File

@@ -42,20 +42,17 @@ add_executable(
src/main.c
src/meta.h
src/resources.c
src/toolbar.c
src/toolbar.h
src/window.c
src/window.h
src/start/action.c
src/start/action.h
src/start/placeslist.c
src/start/placeslist.h
src/start/programslist.c
src/start/programslist.h
src/start/startbutton.c
src/start/startbutton.h
src/start/startmenu.c
src/start/startmenu.h
src/start/startmenuitem.c
src/start/startmenuitem.h
src/start/menumod.c
src/start/menumod.h
src/start/personal.c
src/start/personal.h
src/start/shared.h
src/start/toolbar.c
src/start/toolbar.h
src/start/util.c
src/start/util.h
src/systray/behaviour.c
@@ -64,10 +61,14 @@ add_executable(
src/systray/clock.h
src/systray/notifarea.c
src/systray/notifarea.h
src/systray/toolbar.c
src/systray/toolbar.h
src/systray/volume.c
src/systray/volume.h
src/taskbuttons/taskbuttonbar.c
src/taskbuttons/taskbuttonbar.h
src/taskbuttons/toolbar.c
src/taskbuttons/toolbar.h
src/taskbuttons/windowmonitor.c
src/taskbuttons/windowmonitor.h
)

View File

@@ -0,0 +1,852 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkBox" id="main-box">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkEventBox" id="eventbox-userpic">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-username-horz">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<style>
<class name="start-userpane"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="label-username-vert">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="angle">90</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack-type">end</property>
<property name="position">0</property>
</packing>
</child>
<style>
<class name="start-vuserpane"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="WinTCMenuModded" id="menubar-programs">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="pack-direction">ttb</property>
<child>
<object class="GtkSeparatorMenuItem" id="separator-all-programs">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="valign">end</property>
<property name="vexpand">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem-all-programs">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">center</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">All Programs</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<style>
<class name="arrow"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<style>
<class name="start-all-programs"/>
</style>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<style>
<class name="start-programs-column"/>
</style>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkMenuBar" id="menubar-places">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="pack-direction">ttb</property>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">folder-documents</property>
<property name="icon-size">3</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label">%PLACE_DOCUMENTS%</property>
<property name="max-width-chars">24</property>
<property name="tooltip-text" translatable="yes">Opens the My Documents folder, where you can store letters, reports, notes, and other kinds of documents.</property>
<property name="wrap">True</property>
<property name="xalign">0.0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<style>
<class name="significant"/>
</style>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem-recent-docs">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">document-open-recent</property>
<property name="icon-size">3</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label">%PLACE_RECENTS%</property>
<property name="max-width-chars">24</property>
<property name="tooltip-text" translatable="yes">Displays recently opened documents and folders.</property>
<property name="wrap">True</property>
<property name="xalign">0.0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<style>
<class name="significant"/>
</style>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">folder-pictures</property>
<property name="icon-size">3</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label">%PLACE_PICTURES%</property>
<property name="max-width-chars">24</property>
<property name="tooltip-text" translatable="yes">Opens the My Pictures folder, where you can store digital photos, images, and graphics files.</property>
<property name="wrap">True</property>
<property name="xalign">0.0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<style>
<class name="significant"/>
</style>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">folder-music</property>
<property name="icon-size">3</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label">%PLACE_MUSIC%</property>
<property name="max-width-chars">24</property>
<property name="tooltip-text" translatable="yes">Opens the My Music folder, where you can store music and other audio files.</property>
<property name="wrap">True</property>
<property name="xalign">0.0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<style>
<class name="significant"/>
</style>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">computer</property>
<property name="icon-size">3</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label">%PLACE_DRIVES%</property>
<property name="max-width-chars">24</property>
<property name="tooltip-text" translatable="yes">Gives access to, and information about, the disk drives, cameras, scanners, and other hardware connected to your computer.</property>
<property name="wrap">True</property>
<property name="xalign">0.0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<style>
<class name="significant"/>
</style>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">preferences-other</property>
<property name="icon-size">3</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label">%PLACE_CONTROLPANEL%</property>
<property name="max-width-chars">24</property>
<property name="tooltip-text" translatable="yes">Provides options for you to customize the appearance and functionality of your computer, add or remove programs, and set up network connections and user accounts.</property>
<property name="wrap">True</property>
<property name="xalign">0.0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">preferences-desktop-default-applications</property>
<property name="icon-size">3</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Set Program Access and Defaults</property>
<property name="max-width-chars">24</property>
<property name="tooltip-text" translatable="yes">Chooses default programs for certain activities, such as Web browsing or sending e-mail, and specifies which programs are accessible from the Start menu, desktop, and other locations.</property>
<property name="wrap">True</property>
<property name="xalign">0.0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">preferences-system-network</property>
<property name="icon-size">3</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Connect To...</property>
<property name="max-width-chars">24</property>
<property name="tooltip-text" translatable="yes">Connects to other computers, networks, and the Internet.</property>
<property name="wrap">True</property>
<property name="xalign">0.0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">printer</property>
<property name="icon-size">3</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label">%PLACE_PRINTERS%</property>
<property name="max-width-chars">24</property>
<property name="tooltip-text" translatable="yes">Shows installed printers and fax printers and helps you add new ones.</property>
<property name="wrap">True</property>
<property name="xalign">0.0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">help-browser</property>
<property name="icon-size">3</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Help and Support</property>
<property name="max-width-chars">24</property>
<property name="tooltip-text" translatable="yes">Opens a central location for Help topics, tutorials, troubleshooting, and other support services.</property>
<property name="wrap">True</property>
<property name="xalign">0.0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">system-search</property>
<property name="icon-size">3</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Search</property>
<property name="max-width-chars">24</property>
<property name="tooltip-text" translatable="yes">Opens a window where you can pick search options and work with search results.</property>
<property name="wrap">True</property>
<property name="xalign">0.0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">horizontal</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">system-run</property>
<property name="icon-size">3</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Run...</property>
<property name="max-width-chars">24</property>
<property name="tooltip-text" translatable="yes">Opens a program, folder, document, or Web site.</property>
<property name="wrap">True</property>
<property name="xalign">0.0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<style>
<class name="start-places-column"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<style>
<class name="start-columns"/>
</style>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkButton" id="button-shutdown">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<placeholder/>
</child>
<style>
<class name="shutdown-icon"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Turn Off Computer</property>
<property name="tooltip-text" translatable="yes">Provides options for turning off or restarting your computer, or for activating Stand By or Hibernate modes.</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack-type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button-logoff">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
<style>
<class name="logoff-icon"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Log Off</property>
<property name="tooltip-text" translatable="yes">Provides options for closing your programs and logging off, or for leaving your programs running and switching to another user.</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
</child>
<style>
<class name="start-logoffpane"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</interface>

View File

@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/uk/oddmatics/wintc/taskband">
<file>personal-menu.ui</file>
<file>start-button.ui</file>
<file>start-menu.css</file>
<file>volume-popup.css</file>
</gresource>

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkToggleButton" id="start-button">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="receives-default">False</property>
<property name="tooltip-text" translatable="yes">Click here to begin</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<placeholder/>
</child>
<style>
<class name="wintc-flag"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">start</property>
<style>
<class name="lower"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Start</property>
<style>
<class name="upper"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<style>
<class name="wintc-start-button"/>
</style>
</object>
</interface>

View File

@@ -1,4 +1,4 @@
.xp-start-button .lower
.wintc-start-button .lower
{
font-size: 0pt;
}
@@ -13,32 +13,22 @@ box > menubar > separator
margin: 4px 0px;
}
menuitem.xp-start-all-programs
menuitem.start-all-programs > box
{
min-height: 32px;
}
menuitem.xp-start-all-programs > box
{
font-weight: bold;
}
separator.xp-start-all-programs
{
margin-top: 40px;
}
.xp-start-logoffpane button
.start-logoffpane button
{
margin: 8px 3px;
}
.xp-start-logoffpane button:last-child
.start-logoffpane button:last-child
{
margin-right: 8px;
}
.xp-start-userpane box
.start-userpane box
{
background-size: 100% 100%;
box-shadow: 0px 0px 2px 0px rgba(0,0,0,0.75);
@@ -47,12 +37,12 @@ separator.xp-start-all-programs
min-width: 48px;
}
.xp-start-userpane label
.start-userpane label
{
font-size: 16pt;
}
.xp-start-vuserpane label
.start-vuserpane label
{
font-size: 0pt;
}

View File

@@ -1,39 +0,0 @@
#include <gdk/gdk.h>
#include <glib.h>
#include <wintc-comgtk.h>
#include <wintc-exec.h>
#include "action.h"
//
// PUBLIC FUNCTIONS
//
void launch_action(
WinTCAction action_id
)
{
GError* error = NULL;
if (!wintc_launch_action(action_id, &error))
{
wintc_nice_error_and_clear(&error);
}
}
void launch_command(
const gchar* command
)
{
if (command == NULL)
{
g_error("No command specified.");
return;
}
GError* error = NULL;
if (!wintc_launch_command(command, &error))
{
wintc_nice_error_and_clear(&error);
}
}

View File

@@ -1,15 +0,0 @@
#ifndef __ACTION_H__
#define __ACTION_H__
#include <glib.h>
#include <wintc-exec.h>
void launch_action(
WinTCAction action_id
);
void launch_command(
const gchar* command
);
#endif

View File

@@ -0,0 +1,186 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc-comgtk.h>
#include "menumod.h"
//
// FORWARD DECLARATIONS
//
static void wintc_menu_modded_size_allocate(
GtkWidget* widget,
GtkAllocation* allocation
);
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCMenuModdedClass
{
GtkMenuBarClass __parent__;
};
struct _WinTCMenuModded
{
GtkMenuBar __parent__;
};
//
// GTK TYPE DEFINITION & CTORS
//
G_DEFINE_TYPE(
WinTCMenuModded,
wintc_menu_modded,
GTK_TYPE_MENU_BAR
)
static void wintc_menu_modded_class_init(
WinTCMenuModdedClass* klass
)
{
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
widget_class->size_allocate = wintc_menu_modded_size_allocate;
}
static void wintc_menu_modded_init(
WINTC_UNUSED(WinTCMenuModded* self)
) {}
//
// CLASS VIRTUAL METHODS
//
static void wintc_menu_modded_size_allocate(
GtkWidget* widget,
GtkAllocation* allocation
)
{
// Omega giga ultra hax! There's some GTK gadget fancy pants stuff in the
// menu bar's allocate function what we don't have access to, so we chain
// up early for it to handle all that jazz...
//
(GTK_WIDGET_CLASS(wintc_menu_modded_parent_class))
->size_allocate(widget, allocation);
// ...and then assuming that it took care of all the CSS box model business
// for the menu bar itself, we retrieve the allocation that was set, and
// use that to layout the children a *second* time in the way *we* want
//
GtkAllocation menu_allocation;
GtkAllocation remaining_space;
gtk_widget_get_allocation(widget, &menu_allocation);
remaining_space = menu_allocation;
remaining_space.x = 0;
remaining_space.y = 0;
if (
gtk_menu_bar_get_pack_direction(GTK_MENU_BAR(widget))
!= GTK_PACK_DIRECTION_TTB
)
{
// I'm only implementing TTB for now since that's all the Start menu
// needs
//
g_critical("%s", "Modded menu class only supports TTB packing!");
return;
}
// Calculate children's size allocations
//
GArray* allocations;
GtkWidget* child;
GList* children = gtk_container_get_children(GTK_CONTAINER(widget));
GList* li;
gint n_expanders = 0;
gint share_space = 0;
allocations =
g_array_new(
FALSE,
TRUE,
sizeof(GtkRequestedSize)
);
for (li = children; li; li = li->next)
{
GtkRequestedSize request;
gint toggle_size;
child = li->data;
if (!gtk_widget_get_visible(child))
{
continue;
}
if (gtk_widget_get_vexpand(child))
{
n_expanders++;
}
request.data = child;
gtk_widget_get_preferred_height_for_width(
child,
menu_allocation.width,
&(request.minimum_size),
&(request.natural_size)
);
gtk_menu_item_toggle_size_request(
GTK_MENU_ITEM(child),
&toggle_size
);
request.minimum_size += toggle_size;
request.natural_size += toggle_size;
gtk_menu_item_toggle_size_allocate(
GTK_MENU_ITEM(child),
toggle_size
);
g_array_append_val(allocations, request);
remaining_space.height -= request.minimum_size;
}
remaining_space.height =
gtk_distribute_natural_allocation(
remaining_space.height,
allocations->len,
(GtkRequestedSize*) allocations->data
);
if (n_expanders > 0)
{
share_space = remaining_space.height / n_expanders;
}
for (guint i = 0; i < allocations->len; i++)
{
GtkAllocation child_alloc = remaining_space;
GtkRequestedSize* request = &g_array_index(
allocations,
GtkRequestedSize,
i
);
child_alloc.height = request->minimum_size;
if (gtk_widget_get_vexpand(request->data))
{
child_alloc.height += share_space;
}
remaining_space.y += child_alloc.height;
gtk_widget_size_allocate(
request->data,
&child_alloc
);
}
g_list_free(children);
g_array_unref(allocations);
}

View File

@@ -0,0 +1,22 @@
#ifndef __MENUMOD_H__
#define __MENUMOD_H__
#include <glib.h>
#include <gtk/gtk.h>
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCMenuModdedClass WinTCMenuModdedClass;
typedef struct _WinTCMenuModded WinTCMenuModded;
#define TYPE_WINTC_MENU_MODDED (wintc_menu_modded_get_type())
#define WINTC_MENU_MODDED(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_WINTC_MENU_MODDED, WinTCMenuModded))
#define WINTC_MENU_MODDED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_WINTC_MENU_MODDED, WinTCMenuModdedClass))
#define IS_WINTC_MENU_MODDED(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_WINTC_MENU_MODDED))
#define IS_WINTC_MENU_MODDED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_WINTC_MENU_MODDED))
#define WINTC_MENU_MODDED_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_WINTC_MENU_MODDED, WinTCMenuModded))
GType wintc_menu_modded_get_type(void) G_GNUC_CONST;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
#ifndef __PERSONAL_START_H__
#define __PERSONAL_START_H__
#include <glib.h>
#include <gtk/gtk.h>
#include "shared.h"
//
// INTERNAL FUNCTIONS
//
void close_personal_menu(
WinTCToolbarStart* toolbar_start
);
void create_personal_menu(
WinTCToolbarStart* toolbar_start
);
void destroy_personal_menu(
WinTCToolbarStart* toolbar_start
);
void open_personal_menu(
WinTCToolbarStart* toolbar_start
);
#endif

View File

@@ -1,175 +0,0 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc-comgtk.h>
#include <wintc-exec.h>
#include "startmenuitem.h"
#include "placeslist.h"
#include "util.h"
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _PlacesListClass
{
GtkMenuBarClass __parent__;
};
struct _PlacesList
{
GtkMenuBar __parent__;
};
//
// FORWARD DECLARATIONS
//
static void places_list_finalize(
GObject* object
);
static void places_list_append_item(
PlacesList* places_list,
WinTCAction action_id,
gboolean significant
);
static void places_list_append_separator(
PlacesList* places_list
);
//
// GTK TYPE DEFINITION & CTORS
//
G_DEFINE_TYPE(PlacesList, places_list, GTK_TYPE_MENU_BAR)
static void places_list_class_init(
PlacesListClass* klass
)
{
GObjectClass* gclass = G_OBJECT_CLASS(klass);
gclass->finalize = places_list_finalize;
}
static void places_list_init(
PlacesList* self
)
{
// Set up structure
//
gtk_menu_bar_set_pack_direction(
GTK_MENU_BAR(self),
GTK_PACK_DIRECTION_TTB
);
places_list_append_item(
self,
WINTC_ACTION_MYDOCS,
TRUE
);
places_list_append_item(
self,
WINTC_ACTION_MYRECENTS,
TRUE
);
places_list_append_item(
self,
WINTC_ACTION_MYPICS,
TRUE
);
places_list_append_item(
self,
WINTC_ACTION_MYMUSIC,
TRUE
);
places_list_append_item(
self,
WINTC_ACTION_MYCOMP,
TRUE
);
places_list_append_separator(self);
places_list_append_item(
self,
WINTC_ACTION_CONTROL,
FALSE
);
places_list_append_item(
self,
WINTC_ACTION_MIMEMGMT,
FALSE
);
places_list_append_item(
self,
WINTC_ACTION_CONNECTTO,
FALSE
);
places_list_append_item(
self,
WINTC_ACTION_PRINTERS,
FALSE
);
places_list_append_separator(self);
places_list_append_item(
self,
WINTC_ACTION_HELP,
FALSE
);
places_list_append_item(
self,
WINTC_ACTION_SEARCH,
FALSE
);
places_list_append_item(
self,
WINTC_ACTION_RUN,
FALSE
);
}
//
// FINALIZE
//
static void places_list_finalize(
GObject* object
)
{
(*G_OBJECT_CLASS(places_list_parent_class)->finalize) (object);
}
//
// PRIVATE FUNCTIONS
//
static void places_list_append_item(
PlacesList* places_list,
WinTCAction action_id,
gboolean significant
)
{
GtkWidget* item = start_menu_item_new_from_action(action_id);
// If the item is significant, add the style
//
if (significant)
{
wintc_widget_add_style_class(item, "significant");
}
// FIXME: Shift 24 size to constant
//
start_menu_item_set_icon_size(START_MENU_ITEM(item), 24);
gtk_menu_shell_append(GTK_MENU_SHELL(places_list), item);
}
static void places_list_append_separator(
PlacesList* places_list
)
{
GtkWidget* separator = gtk_separator_menu_item_new();
gtk_menu_shell_append(GTK_MENU_SHELL(places_list), separator);
}

View File

@@ -1,26 +0,0 @@
#ifndef __PLACESLIST_H__
#define __PLACESLIST_H__
#include <glib.h>
#include <gtk/gtk.h>
G_BEGIN_DECLS
//
// GTK OOP BOILERPLATE
//
typedef struct _PlacesListClass PlacesListClass;
typedef struct _PlacesList PlacesList;
#define TYPE_PLACES_LIST (places_list_get_type())
#define PLACES_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_PLACES_LIST, PlacesList))
#define PLACES_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_PLACES_LIST, PlacesListClass))
#define IS_PLACES_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_PLACES_LIST))
#define IS_PLACES_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_PLACES_LIST))
#define PLACES_LIST_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_PLACES_LIST, PlacesListClass))
GType places_list_get_type(void) G_GNUC_CONST;
G_END_DECLS
#endif

View File

@@ -1,283 +0,0 @@
#include <garcon/garcon.h>
#include <garcon-gtk/garcon-gtk.h>
#include <gio/gdesktopappinfo.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <wintc-comgtk.h>
#include <wintc-exec.h>
#include "../meta.h"
#include "programslist.h"
#include "startmenuitem.h"
#include "util.h"
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _ProgramsListClass
{
GtkMenuBarClass __parent__;
};
struct _ProgramsList
{
GtkMenuBar __parent__;
};
//
// FORWARD DECLARATIONS
//
static void programs_list_finalize(
GObject* object
);
static void programs_list_append_all_programs_item(
ProgramsList* programs_list
);
static void programs_list_append_default_items(
ProgramsList* programs_list
);
static void programs_list_append_separator(
ProgramsList* programs_list,
const gchar* style_class
);
static void programs_list_append_top_items(
ProgramsList* programs_list,
gint count
);
//
// GTK TYPE DEFINITION & CTORS
//
G_DEFINE_TYPE(ProgramsList, programs_list, GTK_TYPE_MENU_BAR)
static void programs_list_class_init(
ProgramsListClass* klass
)
{
GObjectClass* gclass = G_OBJECT_CLASS(klass);
gclass->finalize = programs_list_finalize;
}
static void programs_list_init(
ProgramsList* self
)
{
// Set up structure
//
gtk_menu_bar_set_pack_direction(
GTK_MENU_BAR(self),
GTK_PACK_DIRECTION_TTB
);
programs_list_refresh(self);
}
//
// PUBLIC FUNCTIONS
//
void programs_list_refresh(
ProgramsList* programs_list
)
{
programs_list_append_default_items(programs_list);
programs_list_append_separator(programs_list, NULL);
programs_list_append_top_items(programs_list, 6);
programs_list_append_separator(programs_list, "xp-start-all-programs");
programs_list_append_all_programs_item(programs_list);
}
//
// FINALIZE
//
static void programs_list_finalize(
GObject* object
)
{
(*G_OBJECT_CLASS(programs_list_parent_class)->finalize) (object);
}
//
// PRIVATE FUNCTIONS
//
static void programs_list_append_all_programs_item(
ProgramsList* programs_list
)
{
GtkWidget* item = gtk_menu_item_new();
//
// The layout of the item contents is such that we can have the text and
// arrow centered
//
// We have an outer box, which contains the label and a box that represents
// the arrow (should the theme decide to style one)
//
// Outer box
//
GtkWidget* outer_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_halign(outer_box, GTK_ALIGN_CENTER);
// All programs text
//
GtkWidget* all_programs_label = gtk_label_new(_("All Programs"));
// 'Arrow' box
//
GtkWidget* arrow_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
// Set garcon menu
//
GarconMenu* programs_menu = garcon_menu_new_for_path(
WINTC_ASSETS_DIR "/shell-res/start-menu.menu"
);
GtkWidget* programs_submenu = garcon_gtk_menu_new(programs_menu);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), programs_submenu);
// Set style
//
wintc_widget_add_style_class(item, "xp-start-all-programs");
wintc_widget_add_style_class(arrow_box, "arrow");
// Box up
//
gtk_box_pack_start(GTK_BOX(outer_box), all_programs_label, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(outer_box), arrow_box, FALSE, FALSE, 0);
gtk_container_add(GTK_CONTAINER(item), outer_box);
gtk_menu_shell_append(GTK_MENU_SHELL(programs_list), item);
}
static void programs_list_append_default_items(
ProgramsList* programs_list
)
{
const gchar* imsg = _("Opens your Internet browser.");
const gchar* emsg = _("Opens your e-mail program so you can send or read a message.");
// Load desktop entries and create menu items
//
GDesktopAppInfo* internet_entry = wintc_query_mime_handler(
"x-scheme-handler/http",
NULL
);
GDesktopAppInfo* email_entry = wintc_query_mime_handler(
"x-scheme-handler/mailto",
NULL
);
//
// FIXME: Handle NULL entries here! ATM there is a bodge in startmenuitem.c, which
// isn't really the right place for it (since in future, the desktop entry
// constructor could be used for pinned items!)
//
// (Also we throw away the error, it should be handled as well ofc, I'm too
// lazy to do that this evening)
//
GtkWidget* internet_item = start_menu_item_new_from_desktop_entry(
internet_entry,
_("Internet"),
imsg
);
GtkWidget* email_item = start_menu_item_new_from_desktop_entry(
email_entry,
_("E-mail"),
emsg
);
// FIXME: Shift 32 size to constant
//
start_menu_item_set_icon_size(START_MENU_ITEM(internet_item), 32);
start_menu_item_set_icon_size(START_MENU_ITEM(email_item), 32);
g_clear_object(&internet_entry);
g_clear_object(&email_entry);
gtk_menu_shell_append(GTK_MENU_SHELL(programs_list), internet_item);
gtk_menu_shell_append(GTK_MENU_SHELL(programs_list), email_item);
}
static void programs_list_append_separator(
ProgramsList* programs_list,
const gchar* style_class
)
{
GtkWidget* separator = gtk_separator_menu_item_new();
if (style_class != NULL)
{
wintc_widget_add_style_class(separator, style_class);
}
gtk_menu_shell_append(GTK_MENU_SHELL(programs_list), separator);
}
static void programs_list_append_top_items(
ProgramsList* programs_list,
gint count
)
{
GarconMenu* all_entries = garcon_menu_new_for_path(
WINTC_ASSETS_DIR "/shell-res/all.menu"
);
GError* load_error = NULL;
if (!garcon_menu_load(all_entries, NULL, &load_error))
{
wintc_log_error_and_clear(&load_error);
return;
}
// FIXME: In future we will need some >>>algorithm<<< to come up with a 'top'
// programs list to display here, and also reserve the last slot for the
// latest newly added program, if any
//
// For now we simply grab the first items that are pulled in via the
// all.menu file
//
GList* elements = garcon_menu_get_elements(all_entries);
GList* li = elements;
gint i = 0;
GtkWidget* menu_item;
while (i < count && li != NULL)
{
if (
GARCON_IS_MENU_ITEM(li->data) &&
!garcon_menu_item_get_no_display(li->data)
)
{
menu_item =
start_menu_item_new_from_garcon_item(
GARCON_MENU_ITEM(li->data),
NULL,
NULL
);
// FIXME: Shift 32 size to constant
//
start_menu_item_set_icon_size(START_MENU_ITEM(menu_item), 32);
gtk_menu_shell_append(GTK_MENU_SHELL(programs_list), menu_item);
// We only count items we actually added to the increment
//
i++;
}
li = li->next;
}
g_list_free(g_steal_pointer(&elements));
g_clear_object(&all_entries);
}

View File

@@ -1,33 +0,0 @@
#ifndef __PROGRAMSLIST_H__
#define __PROGRAMSLIST_H__
#include <glib.h>
#include <gtk/gtk.h>
G_BEGIN_DECLS
//
// GTK OOP BOILERPLATE
//
typedef struct _ProgramsListClass ProgramsListClass;
typedef struct _ProgramsList ProgramsList;
#define TYPE_PROGRAMS_LIST (programs_list_get_type())
#define PROGRAMS_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_PROGRAMS_LIST, ProgramsList))
#define PROGRAMS_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_PROGRAMS_LIST, ProgramsListClass))
#define IS_PROGRAMS_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_PROGRAMS_LIST))
#define IS_PROGRAMS_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_PROGRAMS_LIST))
#define PROGRAMS_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_PROGRAMS_LIST, ProgramsListClass))
GType programs_list_get_type(void) G_GNUC_CONST;
//
// PUBLIC FUNCTIONS
//
void programs_list_refresh(
ProgramsList* programs_list
);
G_END_DECLS
#endif

View File

@@ -0,0 +1,54 @@
#ifndef __SHARED_START_H__
#define __SHARED_START_H__
//
// INTERNAL STRUCTS
//
typedef struct _PersonalStartMenuData
{
// UI
//
GtkWidget* popup_menu;
GtkWidget* button_logoff;
GtkWidget* button_shutdown;
GtkWidget* eventbox_userpic;
GtkWidget* menubar_places;
GtkWidget* menubar_programs;
GtkWidget* menuitem_all_programs;
GtkWidget* separator_all_programs;
// UI state
//
gboolean sync_menu_refresh;
// Custom style contexts
//
GtkStyleProvider* style_userpic;
// Signal tuples
//
GArray* tuples_places;
GArray* tuples_programs;
} PersonalStartMenuData;
typedef struct _WinTCToolbarStartClass
{
WinTCTaskbandToolbarClass __parent__;
} WinTCToolbarStartClass;
typedef struct _WinTCToolbarStart
{
WinTCTaskbandToolbar __parent__;
// Personal data struct
//
PersonalStartMenuData personal;
// UI state
//
gboolean sync_button;
gboolean sync_menu_should_close;
} WinTCToolbarStart;
#endif

View File

@@ -1,173 +0,0 @@
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <wintc-comgtk.h>
#include "../meta.h"
#include "startbutton.h"
#include "startmenu.h"
#include "util.h"
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _StartButtonPrivate
{
StartMenu* menu;
gboolean synchronizing;
};
struct _StartButtonClass
{
GtkToggleButtonClass __parent__;
};
struct _StartButton
{
GtkToggleButton __parent__;
StartButtonPrivate* priv;
};
//
// FORWARD DECLARATIONS
//
static void on_clicked(
GtkButton* button,
gpointer user_data
);
static void on_start_menu_hidden(
GtkWidget* widget,
gpointer user_data
);
//
// GTK TYPE DEFINITION & CTORS
//
G_DEFINE_TYPE_WITH_CODE(
StartButton,
start_button,
GTK_TYPE_TOGGLE_BUTTON,
G_ADD_PRIVATE(StartButton)
)
static void start_button_class_init(
WINTC_UNUSED(StartButtonClass* klass)
) {}
static void start_button_init(
StartButton* self
)
{
self->priv = start_button_get_instance_private(self);
self->priv->synchronizing = FALSE;
//
// The layout here - we use a box to represent the icon next to the 'start' text
// so that themes can apply their own icon here (important because the Plex style
// has a white Windows flag instead of the coloured one in Luna and other XP
// styles)
//
// Outer box
//
GtkWidget* outer_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
// 'Flag icon' box
//
GtkWidget* icon_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
// Start text
//
// NOTE: We add two labels for uppercase and lowercase 'start' text, this is so
// that themes can hide one or the other via font-size: 0pt
//
GtkWidget* start_label_l = gtk_label_new(_("start"));
GtkWidget* start_label_u = gtk_label_new(_("Start"));
gtk_box_pack_start(GTK_BOX(outer_box), icon_box, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(outer_box), start_label_l, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(outer_box), start_label_u, FALSE, FALSE, 0);
gtk_container_add(GTK_CONTAINER(self), outer_box);
gtk_widget_set_tooltip_text(GTK_WIDGET(self), _("Click here to begin"));
// Add style class
//
wintc_widget_add_style_class(GTK_WIDGET(self), "xp-start-button");
wintc_widget_add_style_class(icon_box, "xp-flag");
wintc_widget_add_style_class(start_label_l, "lower");
wintc_widget_add_style_class(start_label_u, "upper");
// Create menu
//
self->priv->menu = start_menu_new(GTK_WIDGET(self));
g_signal_connect(
G_OBJECT(self),
"clicked",
G_CALLBACK(on_clicked),
NULL
);
connect_start_menu_closed_signal(
self->priv->menu,
G_CALLBACK(on_start_menu_hidden)
);
}
//
// PUBLIC FUNCTIONS
//
GtkWidget* start_button_new(void)
{
return GTK_WIDGET(
g_object_new(TYPE_START_BUTTON, NULL)
);
}
//
// CALLBACKS
//
static void on_clicked(
GtkButton* button,
WINTC_UNUSED(gpointer user_data)
)
{
StartButton* start_button = START_BUTTON(button);
if (start_button->priv->synchronizing)
{
return;
}
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
{
start_menu_present(start_button->priv->menu);
}
else
{
start_menu_close(start_button->priv->menu);
}
}
static void on_start_menu_hidden(
WINTC_UNUSED(GtkWidget* widget),
gpointer user_data
)
{
StartButton* start_button = START_BUTTON(user_data);
start_button->priv->synchronizing = TRUE;
gtk_toggle_button_set_active(
GTK_TOGGLE_BUTTON(start_button),
FALSE
);
start_button->priv->synchronizing = FALSE;
}

View File

@@ -1,34 +0,0 @@
#ifndef __STARTBUTTON_H__
#define __STARTBUTTON_H__
#include <glib.h>
#include <gtk/gtk.h>
#include "startmenu.h"
G_BEGIN_DECLS
//
// GTK OOP BOILERPLATE
//
typedef struct _StartButtonPrivate StartButtonPrivate;
typedef struct _StartButtonClass StartButtonClass;
typedef struct _StartButton StartButton;
#define TYPE_START_BUTTON (start_button_get_type())
#define START_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_START_BUTTON, StartButton))
#define START_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_START_BUTTON, StartButtonClass))
#define IS_START_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_START_BUTTON))
#define IS_START_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_START_BUTTON))
#define START_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_START_BUTTON, StartButtonClass))
GType start_button_get_type(void) G_GNUC_CONST;
//
// PUBLIC FUNCTIONS
//
GtkWidget* start_button_new(void);
G_END_DECLS
#endif

View File

@@ -1,592 +0,0 @@
#include <gdk/gdk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <pwd.h>
#include <unistd.h>
#include <wintc-comgtk.h>
#include <wintc-shelldpa.h>
#include "../meta.h"
#include "action.h"
#include "placeslist.h"
#include "programslist.h"
#include "startmenu.h"
#include "util.h"
//
// STRUCTURE DEFINITIONS
//
struct _StartMenu
{
GtkWidget* menu;
GtkWidget* main_box;
GtkWidget* start_button;
GtkStyleProvider* userpic_style_provider;
};
//
// FORWARD DECLARATIONS
//
static void create_logoffpane_structure(
StartMenu* start_menu,
GtkBox* box
);
static void create_places_structure(
StartMenu* start_menu,
GtkBox* box
);
static void create_programs_structure(
StartMenu* start_menu,
GtkBox* box
);
static void create_taskcolumns_structure(
StartMenu* start_menu,
GtkBox* box
);
static void create_userpane_structure(
StartMenu* start_menu,
GtkBox* box
);
static void create_vertical_userpane_structure(
StartMenu* start_menu,
GtkBox* box
);
static void update_userpic(
StartMenu* start_menu
);
static void on_action_button_clicked(
GtkButton* button,
gpointer user_data
);
static gboolean on_focus_out(
GtkWidget* widget,
GdkEvent* event,
gpointer user_data
);
static void on_selection_done(
GtkWidget* widget,
StartMenu* start_menu
);
static void on_userpic_clicked(
GtkWidget* userpic,
GdkEventButton* event
);
//
// PUBLIC FUNCTIONS
//
void connect_start_menu_closed_signal(
StartMenu* start_menu,
GCallback callback
)
{
g_signal_connect(
start_menu->menu,
"hide",
callback,
start_menu->start_button
);
}
void start_menu_close(
StartMenu* start_menu
)
{
gtk_widget_hide(start_menu->menu);
}
StartMenu* start_menu_new(
GtkWidget* start_button
)
{
StartMenu* start_menu = g_new(StartMenu, 1);
// On X11, we must use a GtkWindow, on Wayland we use a GtkPopover - the
// reason for this is because popovers cannot exist outside the bounds of
// the parent window on X11
//
// We use a GtkWindow instead on X11 to work around that, using
// gtk_window_move() -- which obviously doesn't work on Wayland
//
// So... GtkWindow on X11, GtkPopover on Wayland :)
//
if (wintc_get_display_protocol_in_use() == WINTC_DISPPROTO_X11)
{
start_menu->menu = gtk_window_new(GTK_WINDOW_TOPLEVEL);
// Set up hints
//
gtk_window_set_type_hint(
GTK_WINDOW(start_menu->menu),
GDK_WINDOW_TYPE_HINT_POPUP_MENU
);
gtk_window_set_resizable(
GTK_WINDOW(start_menu->menu),
FALSE
);
gtk_window_set_keep_above(
GTK_WINDOW(start_menu->menu),
TRUE
);
gtk_window_stick(GTK_WINDOW(start_menu->menu));
gtk_window_set_skip_taskbar_hint(
GTK_WINDOW(start_menu->menu),
TRUE
);
gtk_window_set_title(
GTK_WINDOW(start_menu->menu),
"Start menu"
);
gtk_widget_set_events(
GTK_WIDGET(start_menu->menu),
GDK_FOCUS_CHANGE_MASK
);
// Set up signals
//
g_signal_connect(
start_menu->menu,
"delete-event",
G_CALLBACK(gtk_widget_hide_on_delete),
NULL
);
g_signal_connect(
start_menu->menu,
"focus-out-event",
G_CALLBACK(on_focus_out),
NULL
);
// Set titlebar to the fake titlebar box
//
GtkWidget* fake_titlebar = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_window_set_titlebar(
GTK_WINDOW(start_menu->menu),
fake_titlebar
);
}
else if (wintc_get_display_protocol_in_use() == WINTC_DISPPROTO_WAYLAND)
{
start_menu->menu = gtk_popover_new(start_button);
}
// Set up structure
//
start_menu->main_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
create_userpane_structure(start_menu, GTK_BOX(start_menu->main_box));
create_taskcolumns_structure(start_menu, GTK_BOX(start_menu->main_box));
create_logoffpane_structure(start_menu, GTK_BOX(start_menu->main_box));
gtk_container_add(GTK_CONTAINER(start_menu->menu), start_menu->main_box);
// Add style class
//
wintc_widget_add_style_class(GTK_WIDGET(start_menu->menu), "xp-start-menu");
gtk_widget_show_all(start_menu->main_box);
// Attach button
//
start_menu->start_button = start_button;
return start_menu;
}
void start_menu_present(
StartMenu* start_menu
)
{
gint height;
gint x;
gint y;
if (wintc_get_display_protocol_in_use() == WINTC_DISPPROTO_X11)
{
gtk_window_present_with_time(
GTK_WINDOW(start_menu->menu),
GDK_CURRENT_TIME
);
height = gtk_widget_get_allocated_height(start_menu->main_box);
gdk_window_get_origin(
gtk_widget_get_window(start_menu->start_button),
&x,
&y
);
gtk_window_move(
GTK_WINDOW(start_menu->menu),
x,
y - height
);
}
else
{
gtk_widget_show(start_menu->menu);
}
}
//
// PRIVATE FUNCTIONS
//
static void create_logoffpane_structure(
WINTC_UNUSED(StartMenu* start_menu),
GtkBox* box
)
{
GtkWidget* logoffpane_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
//
// These are a couple ordinary buttons, except we have an extra box before the
// label so that themes can add an icon
//
// The reason for not using the gtk-icon-theme here is because the themes need
// to be able to override the image, AND they need to provide a 'hot' graphic for
// when the buttons are hovered
//
// Log off button
//
GtkWidget* logoff_button = gtk_button_new();
GtkWidget* logoff_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget* logoff_icon_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget* logoff_label = gtk_label_new(_("Log Off"));
gtk_box_pack_start(GTK_BOX(logoff_box), logoff_icon_box, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(logoff_box), logoff_label, FALSE, FALSE, 0);
gtk_container_add(GTK_CONTAINER(logoff_button), logoff_box);
g_signal_connect(
G_OBJECT(logoff_button),
"clicked",
G_CALLBACK(on_action_button_clicked),
GINT_TO_POINTER(WINTC_ACTION_LOGOFF)
);
gtk_widget_set_tooltip_text(
logoff_button,
_("Provides options for closing your programs and logging off, or for leaving your programs running and switching to another user.")
);
wintc_widget_add_style_class(logoff_icon_box, "logoff-icon");
// Shut down button
//
GtkWidget* shutdown_button = gtk_button_new();
GtkWidget* shutdown_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget* shutdown_icon_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget* shutdown_label = gtk_label_new(_("Turn Off Computer"));
gtk_box_pack_start(GTK_BOX(shutdown_box), shutdown_icon_box, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(shutdown_box), shutdown_label, FALSE, FALSE, 0);
gtk_container_add(GTK_CONTAINER(shutdown_button), shutdown_box);
g_signal_connect(
G_OBJECT(shutdown_button),
"clicked",
G_CALLBACK(on_action_button_clicked),
GINT_TO_POINTER(WINTC_ACTION_SHUTDOWN)
);
gtk_widget_set_tooltip_text(
shutdown_button,
_("Provides options for turning off or restarting your computer, or for activating Stand By or Hibernate modes.")
);
wintc_widget_add_style_class(shutdown_icon_box, "shutdown-icon");
// Pack box
//
gtk_box_pack_end(GTK_BOX(logoffpane_box), shutdown_button, FALSE, FALSE, 0);
gtk_box_pack_end(GTK_BOX(logoffpane_box), logoff_button, FALSE, FALSE, 0);
gtk_box_pack_start(box, logoffpane_box, FALSE, FALSE, 0);
// Add style class
//
wintc_widget_add_style_class(GTK_WIDGET(logoffpane_box), "xp-start-logoffpane");
}
static void create_places_structure(
StartMenu* start_menu,
GtkBox* box
)
{
GtkWidget* places_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
// Create menu
//
GtkWidget* places_list = GTK_WIDGET(g_object_new(TYPE_PLACES_LIST, NULL));
// Pack box
//
gtk_box_pack_start(GTK_BOX(places_box), places_list, TRUE, TRUE, 0);
gtk_box_pack_start(box, places_box, TRUE, TRUE, 0);
// Set up signals
//
GList* menu_children =
gtk_container_get_children(
GTK_CONTAINER(places_list)
);
wintc_signal_connect_list(
menu_children,
"enter-notify-event",
G_CALLBACK(wintc_menu_shell_select_on_enter),
places_list
);
wintc_signal_connect_list(
menu_children,
"leave-notify-event",
G_CALLBACK(wintc_menu_shell_deselect_on_leave),
places_list
);
g_list_free(g_steal_pointer(&menu_children));
g_signal_connect(
places_list,
"selection-done",
G_CALLBACK(on_selection_done),
start_menu
);
// Add style class
//
wintc_widget_add_style_class(GTK_WIDGET(places_box), "xp-start-places-column");
}
static void create_programs_structure(
StartMenu* start_menu,
GtkBox* box
)
{
GtkWidget* programs_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
// Create menu
//
GtkWidget* programs_list = GTK_WIDGET(g_object_new(TYPE_PROGRAMS_LIST, NULL));
// Pack box
//
gtk_box_pack_start(GTK_BOX(programs_box), programs_list, TRUE, TRUE, 0);
gtk_box_pack_start(box, programs_box, TRUE, TRUE, 0);
// Set up signals
//
GList* menu_children =
gtk_container_get_children(
GTK_CONTAINER(programs_list)
);
wintc_signal_connect_list(
menu_children,
"enter-notify-event",
G_CALLBACK(wintc_menu_shell_select_on_enter),
programs_list
);
wintc_signal_connect_list(
menu_children,
"leave-notify-event",
G_CALLBACK(wintc_menu_shell_deselect_on_leave),
programs_list
);
g_list_free(g_steal_pointer(&menu_children));
g_signal_connect(
programs_list,
"selection-done",
G_CALLBACK(on_selection_done),
start_menu
);
// Add style class
//
wintc_widget_add_style_class(GTK_WIDGET(programs_box), "xp-start-programs-column");
}
static void create_taskcolumns_structure(
StartMenu* start_menu,
GtkBox* box
)
{
// Create structure
//
GtkWidget* columns_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
create_vertical_userpane_structure(start_menu, GTK_BOX(columns_box));
create_programs_structure(start_menu, GTK_BOX(columns_box));
create_places_structure(start_menu, GTK_BOX(columns_box));
gtk_box_pack_start(box, columns_box, TRUE, TRUE, 0);
// Add style class
//
wintc_widget_add_style_class(GTK_WIDGET(columns_box), "xp-start-columns");
}
static void create_userpane_structure(
StartMenu* start_menu,
GtkBox* box
)
{
GtkWidget* userpane_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
// User profile picture
//
GtkStyleContext* context;
GtkWidget* pic_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget* pic_event_box = gtk_event_box_new();
start_menu->userpic_style_provider =
GTK_STYLE_PROVIDER(gtk_css_provider_new());
context = gtk_widget_get_style_context(pic_box);
gtk_style_context_add_provider(
context,
start_menu->userpic_style_provider,
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
);
update_userpic(start_menu);
gtk_widget_set_events(pic_event_box, GDK_BUTTON_PRESS_MASK);
gtk_box_pack_start(GTK_BOX(pic_box), pic_event_box, TRUE, TRUE, 0);
g_signal_connect(
pic_event_box,
"button-press-event",
G_CALLBACK(on_userpic_clicked),
NULL
);
// Username display
//
struct passwd* user_pwd = getpwuid(getuid());
GtkWidget* username_label = gtk_label_new(user_pwd->pw_name);
// Construct box
//
gtk_box_pack_start(GTK_BOX(userpane_box), pic_box, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(userpane_box), username_label, FALSE, FALSE, 0);
gtk_box_pack_start(box, userpane_box, FALSE, FALSE, 0);
// Add style class
//
wintc_widget_add_style_class(userpane_box, "xp-start-userpane");
}
static void create_vertical_userpane_structure(
WINTC_UNUSED(StartMenu* start_menu),
GtkBox* box
)
{
GtkWidget* userpane_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
// Username display
//
struct passwd* user_pwd = getpwuid(getuid());
GtkWidget* username_label = gtk_label_new(user_pwd->pw_name);
gtk_label_set_angle(GTK_LABEL(username_label), 90);
// Construct box
//
gtk_box_pack_end(GTK_BOX(userpane_box), username_label, FALSE, FALSE, 0);
gtk_box_pack_start(box, userpane_box, FALSE, FALSE, 0);
// Add style class
//
wintc_widget_add_style_class(userpane_box, "xp-start-vuserpane");
}
static void update_userpic(
StartMenu* start_menu
)
{
static gchar* css = NULL;
if (css == NULL)
{
// FIXME: This should read from whatever the XDG path is, probably needs a
// g_strdup_printf for the username
//
css = "* { background-image: url('" WINTC_ASSETS_DIR "/shell-res/fpo-userpic.png'); }";
}
// Give GTK a bump that we want to update the pic
//
gtk_css_provider_load_from_data(
GTK_CSS_PROVIDER(start_menu->userpic_style_provider),
css,
-1,
NULL
);
}
//
// CALLBACKS
//
static void on_action_button_clicked(
WINTC_UNUSED(GtkButton* button),
gpointer user_data
)
{
launch_action(GPOINTER_TO_INT(user_data));
}
static gboolean on_focus_out(
GtkWidget* widget,
WINTC_UNUSED(GdkEvent* event),
WINTC_UNUSED(gpointer user_data)
)
{
gtk_widget_hide(widget);
return TRUE;
}
static void on_selection_done(
WINTC_UNUSED(GtkWidget* widget),
StartMenu* start_menu
)
{
gtk_widget_hide(GTK_WIDGET(start_menu->menu));
}
static void on_userpic_clicked(
WINTC_UNUSED(GtkWidget* userpic),
GdkEventButton* event
)
{
//
// FIXME: Implement this when the user pic cpl is done!
//
if (event->button > 1)
{
return;
}
GError* error = NULL;
g_set_error(
&error,
WINTC_GENERAL_ERROR,
WINTC_GENERAL_ERROR_NOTIMPL,
"Cannot edit user pic yet!"
);
wintc_nice_error_and_clear(&error);
}

View File

@@ -1,31 +0,0 @@
#ifndef __STARTMENU_H__
#define __STARTMENU_H__
#include <gtk/gtk.h>
//
// STRUCTURE DEFINITIONS
//
typedef struct _StartMenu StartMenu;
//
// PUBLIC FUNCTIONS
//
void connect_start_menu_closed_signal(
StartMenu* start_menu,
GCallback callback
);
void start_menu_close(
StartMenu* start_menu
);
StartMenu* start_menu_new(
GtkWidget* start_button
);
void start_menu_present(
StartMenu* start_menu
);
#endif

View File

@@ -1,478 +0,0 @@
#include <garcon/garcon.h>
#include <gdk/gdk.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gio/gdesktopappinfo.h>
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <wintc-comgtk.h>
#include <wintc-exec.h>
#include <wintc-shllang.h>
#include "../meta.h"
#include "action.h"
#include "startmenuitem.h"
#include "util.h"
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _StartMenuItemPrivate
{
StartMenuItem* menuitem;
WinTCAction action;
gchar* cmdline;
gboolean is_action;
GtkWidget* icon;
GtkWidget* label;
GtkWidget* label_generic;
};
struct _StartMenuItemClass
{
GtkMenuItemClass __parent__;
};
struct _StartMenuItem
{
GtkMenuItem __parent__;
StartMenuItemPrivate* priv;
};
//
// FORWARD DECLARATIONS
//
static void start_menu_item_finalize(
GObject* object
);
static GtkWidget* start_menu_item_new_manual(
const gchar* icon_name,
const gchar* program_name,
const gchar* comment,
const gchar* generic_name
);
static void on_menu_item_activate(
GtkWidget* widget,
gpointer user_data
);
//
// GTK TYPE DEFINITIONS & CTORS
//
G_DEFINE_TYPE_WITH_CODE(
StartMenuItem,
start_menu_item,
GTK_TYPE_MENU_ITEM,
G_ADD_PRIVATE(StartMenuItem)
)
static void start_menu_item_class_init(
StartMenuItemClass* klass
)
{
GObjectClass* gclass = G_OBJECT_CLASS(klass);
gclass->finalize = start_menu_item_finalize;
}
static void start_menu_item_init(
StartMenuItem* self
)
{
self->priv = start_menu_item_get_instance_private(self);
g_signal_connect(
G_OBJECT(self),
"activate",
G_CALLBACK(on_menu_item_activate),
NULL
);
}
//
// FINALIZE
//
static void start_menu_item_finalize(
GObject* object
)
{
StartMenuItem* start_menu_item = START_MENU_ITEM(object);
if (start_menu_item->priv->cmdline != NULL)
{
g_free(start_menu_item->priv->cmdline);
}
(*G_OBJECT_CLASS(start_menu_item_parent_class)->finalize) (object);
}
//
// PUBLIC FUNCTIONS
//
GtkWidget* start_menu_item_new_from_action(
WinTCAction action
)
{
const gchar* comment;
const gchar* icon_name;
const gchar* name;
GtkWidget* start_menu_item;
switch (action)
{
case WINTC_ACTION_MYDOCS:
comment = _("Opens the My Documents folder, where you can store letters, reports, notes, and other kinds of documents.");
icon_name = "folder-documents";
name = wintc_get_place_name(WINTC_PLACE_DOCUMENTS);
break;
case WINTC_ACTION_MYRECENTS:
comment = _("Displays recently opened documents and folders.");
icon_name = "document-open-recent";
name = wintc_get_place_name(WINTC_PLACE_RECENTS);
break;
case WINTC_ACTION_MYPICS:
comment = _("Opens the My Pictures folder, where you can store digital photos, images, and graphics files.");
icon_name = "folder-pictures";
name = wintc_get_place_name(WINTC_PLACE_PICTURES);
break;
case WINTC_ACTION_MYMUSIC:
comment = _("Opens the My Music folder, where you can store music and other audio files.");
icon_name = "folder-music";
name = wintc_get_place_name(WINTC_PLACE_MUSIC);
break;
case WINTC_ACTION_MYCOMP:
comment = _("Gives access to, and information about, the disk drives, cameras, scanners, and other hardware connected to your computer.");
icon_name = "computer";
name = wintc_get_place_name(WINTC_PLACE_DRIVES);
break;
case WINTC_ACTION_CONTROL:
comment = _("Provides options for you to customize the appearance and functionality of your computer, add or remove programs, and set up network connections and user accounts.");
icon_name = "preferences-other";
name = wintc_get_place_name(WINTC_PLACE_CONTROLPANEL);
break;
case WINTC_ACTION_MIMEMGMT:
comment = _("Chooses default programs for certain activities, such as Web browsing or sending e-mail, and specifies which programs are accessible from the Start menu, desktop, and other locations.");
icon_name = "preferences-desktop-default-applications";
name = _("Set Program Access and Defaults");
break;
case WINTC_ACTION_CONNECTTO:
comment = _("Connects to other computers, networks, and the Internet.");
icon_name = "preferences-system-network";
name = _("Connect To");
break;
case WINTC_ACTION_PRINTERS:
comment = _("Shows installed printers and fax printers and helps you add new ones.");
icon_name = "printer";
name = wintc_get_place_name(WINTC_PLACE_PRINTERS);
break;
case WINTC_ACTION_HELP:
comment = _("Opens a central location for Help topics, tutorials, troubleshooting, and other support services.");
icon_name = "help-browser";
name = _("Help and Support");
break;
case WINTC_ACTION_SEARCH:
comment = _("Opens a window where you can pick search options and work with search results.");
icon_name = "system-search";
name = _("Search");
break;
case WINTC_ACTION_RUN:
comment = _("Opens a program, folder, document, or Web site.");
icon_name = "system-run";
name = _("Run...");
break;
default:
comment = "Unknown action.";
icon_name = "dialog-error";
name = "Unknown";
break;
}
start_menu_item =
start_menu_item_new_manual(
icon_name,
name,
comment,
NULL
);
// Add action state
//
(START_MENU_ITEM(start_menu_item))->priv->action = action;
(START_MENU_ITEM(start_menu_item))->priv->is_action = TRUE;
return start_menu_item;
}
GtkWidget* start_menu_item_new_from_desktop_entry(
GDesktopAppInfo* entry,
const gchar* generic_name,
const gchar* comment
)
{
// FIXME: Temp bodge for handling NULL desktop entry (handle properly in
// programslist.c)
//
// (We just insert a default item to open the MIME management action)
//
if (entry == NULL)
{
GtkWidget* null_menu_item =
start_menu_item_new_manual(
"important",
"Click to specify a default",
comment != NULL ? comment : "No default program could be identified.",
generic_name
);
(START_MENU_ITEM(null_menu_item))->priv->action = WINTC_ACTION_MIMEMGMT;
(START_MENU_ITEM(null_menu_item))->priv->is_action = TRUE;
return null_menu_item;
}
// Normal code - desktop entry actually exists! Wahey!
//
GAppInfo* app_info = G_APP_INFO(entry);
const gchar* app_desc = g_app_info_get_description(app_info);
const gchar* exe_path = g_app_info_get_executable(app_info);
const gchar* name = g_app_info_get_name(app_info);
gchar* exe_name = g_path_get_basename(exe_path);
GtkWidget* start_menu_item =
start_menu_item_new_manual(
exe_name,
name,
comment != NULL ? comment : app_desc,
generic_name
);
(START_MENU_ITEM(start_menu_item))->priv->cmdline =
wintc_desktop_app_info_get_command(entry);
g_free(exe_name);
return start_menu_item;
}
GtkWidget* start_menu_item_new_from_garcon_item(
GarconMenuItem* item,
const gchar* generic_name,
const gchar* comment
)
{
GtkWidget* start_menu_item =
start_menu_item_new_manual(
garcon_menu_item_get_icon_name(item),
garcon_menu_item_get_name(item),
comment != NULL ?
comment :
garcon_menu_item_get_comment(item),
generic_name
);
(START_MENU_ITEM(start_menu_item))->priv->cmdline =
garcon_menu_item_get_command_expanded(item);
return start_menu_item;
}
void start_menu_item_set_icon_size(
StartMenuItem* item,
gint size
)
{
g_assert(item->priv->icon != NULL);
gtk_image_set_pixel_size(
GTK_IMAGE(item->priv->icon),
size
);
}
//
// PRIVATE FUNCTIONS
//
static GtkWidget* start_menu_item_new_manual(
const gchar* icon_name,
const gchar* program_name,
const gchar* comment,
const gchar* generic_name
)
{
StartMenuItem* start_menu_item =
START_MENU_ITEM(g_object_new(TYPE_START_MENU_ITEM, NULL));
// Application icon
//
start_menu_item->priv->icon =
gtk_image_new_from_icon_name(
icon_name,
GTK_ICON_SIZE_MENU
);
// Depending on if a generic name is specified, we create either a normal item or
// a 'default' item (the kind that go at the top of the Start menu)
//
if (generic_name == NULL) // Normal item
{
// Program name
//
start_menu_item->priv->label =
gtk_label_new(program_name);
// Set up structure
//
GtkWidget* box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start(
GTK_BOX(box),
start_menu_item->priv->icon,
FALSE,
FALSE,
0
);
gtk_box_pack_start(
GTK_BOX(box),
start_menu_item->priv->label,
FALSE,
FALSE,
0
);
gtk_container_add(GTK_CONTAINER(start_menu_item), box);
}
else // Default item
{
// Add style class to distinguish this menu item
//
wintc_widget_add_style_class(
GTK_WIDGET(start_menu_item),
"xp-start-default-item"
);
// Generic program type
//
start_menu_item->priv->label_generic =
gtk_label_new(generic_name);
gtk_widget_set_halign(
start_menu_item->priv->label_generic,
GTK_ALIGN_START
);
// Program name
//
start_menu_item->priv->label =
gtk_label_new(program_name);
// Set up structure
//
GtkWidget* outer_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget* label_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_valign(label_box, GTK_ALIGN_CENTER);
gtk_box_pack_start(
GTK_BOX(label_box),
start_menu_item->priv->label_generic,
FALSE,
FALSE,
0
);
gtk_box_pack_start(
GTK_BOX(label_box),
start_menu_item->priv->label,
FALSE,
FALSE,
0
);
gtk_box_pack_start(
GTK_BOX(outer_box),
start_menu_item->priv->icon,
FALSE,
FALSE,
0
);
gtk_box_pack_start(
GTK_BOX(outer_box),
label_box,
FALSE,
FALSE,
0
);
gtk_container_add(GTK_CONTAINER(start_menu_item), outer_box);
}
// Set program name line wrapping
//
gtk_label_set_line_wrap(
GTK_LABEL(start_menu_item->priv->label),
TRUE
);
gtk_label_set_max_width_chars(
GTK_LABEL(start_menu_item->priv->label),
24
);
gtk_label_set_xalign(
GTK_LABEL(start_menu_item->priv->label),
0.0
);
// Add program comment
//
if (comment != NULL)
{
gchar* real_comment = wintc_str_set_suffix(comment, ".");
gtk_widget_set_tooltip_text(
GTK_WIDGET(start_menu_item),
real_comment
);
g_free(real_comment);
}
return GTK_WIDGET(start_menu_item);
}
//
// CALLBACKS
//
static void on_menu_item_activate(
GtkWidget* widget,
WINTC_UNUSED(gpointer user_data)
)
{
StartMenuItem* start_menu_item = START_MENU_ITEM(widget);
if (start_menu_item->priv->is_action)
{
launch_action(start_menu_item->priv->action);
}
else
{
launch_command(start_menu_item->priv->cmdline);
}
}

View File

@@ -1,51 +0,0 @@
#ifndef __STARTMENUITEM_H__
#define __STARTMENUITEM_H__
#include <garcon/garcon.h>
#include <gio/gdesktopappinfo.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc-exec.h>
G_BEGIN_DECLS
//
// GTK OOP BOILERPLATE
//
typedef struct _StartMenuItemPrivate StartMenuItemPrivate;
typedef struct _StartMenuItemClass StartMenuItemClass;
typedef struct _StartMenuItem StartMenuItem;
#define TYPE_START_MENU_ITEM (start_menu_item_get_type())
#define START_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_START_MENU_ITEM, StartMenuItem))
#define START_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_START_MENU_ITEM, StartMenuItemClass))
#define IS_START_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_START_MENU_ITEM))
#define IS_START_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_START_MENU_ITEM))
#define START_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_START_MENU_ITEM, StartMenuItemClass))
GType start_menu_item_get_type(void) G_GNUC_CONST;
//
// PUBLIC FUNCTIONS
//
GtkWidget* start_menu_item_new_from_action(
WinTCAction action
);
GtkWidget* start_menu_item_new_from_desktop_entry(
GDesktopAppInfo* entry,
const gchar* generic_name,
const gchar* comment
);
GtkWidget* start_menu_item_new_from_garcon_item(
GarconMenuItem* item,
const gchar* generic_name,
const gchar* comment
);
void start_menu_item_set_icon_size(
StartMenuItem* item,
gint size
);
G_END_DECLS
#endif

View File

@@ -0,0 +1,152 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc-comgtk.h>
#include <wintc-shelldpa.h>
#include <wintc-shllang.h>
#include "../toolbar.h"
#include "personal.h"
#include "shared.h"
#include "toolbar.h"
//
// FORWARD DECLARATIONS
//
static void wintc_toolbar_start_dispose(
GObject* object
);
static void on_start_button_toggled(
GtkToggleButton* self,
gpointer user_data
);
//
// GTK TYPE DEFINITION & CTORS
//
G_DEFINE_TYPE(
WinTCToolbarStart,
wintc_toolbar_start,
TYPE_WINTC_TASKBAND_TOOLBAR
)
static void wintc_toolbar_start_class_init(
WinTCToolbarStartClass* klass
)
{
GObjectClass* object_class = G_OBJECT_CLASS(klass);
object_class->dispose = wintc_toolbar_start_dispose;
}
static void wintc_toolbar_start_init(
WinTCToolbarStart* self
)
{
GtkBuilder* builder;
WinTCTaskbandToolbar* toolbar = WINTC_TASKBAND_TOOLBAR(self);
// Default states
//
self->sync_button = FALSE;
self->sync_menu_should_close = FALSE;
// Apply stylesheet for this toolbar
//
GtkCssProvider* css = gtk_css_provider_new();
gtk_css_provider_load_from_resource(
css,
"/uk/oddmatics/wintc/taskband/start-menu.css"
);
gtk_style_context_add_provider_for_screen(
gdk_screen_get_default(),
GTK_STYLE_PROVIDER(css),
GTK_STYLE_PROVIDER_PRIORITY_FALLBACK
);
// Create root widget (Start button)
//
builder =
gtk_builder_new_from_resource(
"/uk/oddmatics/wintc/taskband/start-button.ui"
);
wintc_preprocess_builder_widget_text(builder);
toolbar->widget_root =
GTK_WIDGET(
g_object_ref_sink(
gtk_builder_get_object(builder, "start-button")
)
);
g_object_unref(G_OBJECT(builder));
// Create Start menu widget
// FIXME: Hard coded to the personal menu for now, 'til DBus and stuff is
// understood and we can support a 'Use classic menu' property
//
create_personal_menu(self);
// Attach signals for popup
//
g_signal_connect(
toolbar->widget_root,
"toggled",
G_CALLBACK(on_start_button_toggled),
self
);
}
//
// CLASS VIRTUAL METHODS
//
static void wintc_toolbar_start_dispose(
GObject* object
)
{
WinTCTaskbandToolbar* toolbar = WINTC_TASKBAND_TOOLBAR(object);
WinTCToolbarStart* toolbar_start = WINTC_TOOLBAR_START(object);
// Because we took a reference to the Start button from the builder, we
// must unref it now
//
g_object_unref(toolbar->widget_root);
// FIXME: Only worrying about destroying the personal menu for now until
// the classic menu is available
//
destroy_personal_menu(toolbar_start);
(G_OBJECT_CLASS(wintc_toolbar_start_parent_class))->dispose(object);
}
//
// CALLBACKS
//
static void on_start_button_toggled(
GtkToggleButton* self,
gpointer user_data
)
{
WinTCToolbarStart* toolbar_start = WINTC_TOOLBAR_START(user_data);
if (toolbar_start->sync_button)
{
return;
}
// FIXME: Only dealing with personal menu here until class menu exists
//
if (gtk_toggle_button_get_active(self))
{
open_personal_menu(toolbar_start);
}
else
{
close_personal_menu(toolbar_start);
}
}

View File

@@ -0,0 +1,20 @@
#ifndef __TOOLBAR_START_H__
#define __TOOLBAR_START_H__
#include <glib.h>
#include <gtk/gtk.h>
//
// GTK OOP BOILERPLATE
//
#define TYPE_WINTC_TOOLBAR_START (wintc_toolbar_start_get_type())
#define WINTC_TOOLBAR_START(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_WINTC_TOOLBAR_START, WinTCToolbarStart))
#define WINTC_TOOLBAR_START_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_WINTC_TOOLBAR_START, WinTCToolbarStartClass))
#define IS_WINTC_TOOLBAR_START(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_WINTC_TOOLBAR_START))
#define IS_WINTC_TOOLBAR_START_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_WINTC_TOOLBAR_START))
#define WINTC_TOOLBAR_START_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_WINTC_TOOLBAR_START, WinTCToolbarStart))
GType wintc_toolbar_start_get_type(void) G_GNUC_CONST;
#endif

View File

@@ -0,0 +1,43 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc-comgtk.h>
#include "../toolbar.h"
#include "notifarea.h"
#include "toolbar.h"
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCToolbarNotifAreaClass
{
WinTCTaskbandToolbarClass __parent__;
};
struct _WinTCToolbarNotifArea
{
WinTCTaskbandToolbar __parent__;
};
//
// GTK TYPE DEFINITION & CTORS
//
G_DEFINE_TYPE(
WinTCToolbarNotifArea,
wintc_toolbar_notif_area,
TYPE_WINTC_TASKBAND_TOOLBAR
)
static void wintc_toolbar_notif_area_class_init(
WINTC_UNUSED(WinTCToolbarNotifAreaClass* klass)
) {}
static void wintc_toolbar_notif_area_init(
WinTCToolbarNotifArea* self
)
{
WinTCTaskbandToolbar* toolbar = WINTC_TASKBAND_TOOLBAR(self);
toolbar->widget_root = notification_area_new();
}

View File

@@ -0,0 +1,23 @@
#ifndef __TOOLBAR_NOTIF_AREA_H__
#define __TOOLBAR_NOTIF_AREA_H__
#include <glib.h>
#include <gtk/gtk.h>
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCToolbarNotifAreaClass WinTCToolbarNotifAreaClass;
typedef struct _WinTCToolbarNotifArea WinTCToolbarNotifArea;
#define TYPE_WINTC_TOOLBAR_NOTIF_AREA (wintc_toolbar_notif_area_get_type())
#define WINTC_TOOLBAR_NOTIF_AREA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_WINTC_TOOLBAR_NOTIF_AREA, WinTCToolbarNotifArea))
#define WINTC_TOOLBAR_NOTIF_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_WINTC_TOOLBAR_NOTIF_AREA, WinTCToolbarNotifAreaClass))
#define IS_WINTC_TOOLBAR_NOTIF_AREA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_WINTC_TOOLBAR_NOTIF_AREA))
#define IS_WINTC_TOOLBAR_NOTIF_AREA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_WINTC_TOOLBAR_NOTIF_AREA))
#define WINTC_TOOLBAR_NOTIF_AREA_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_WINTC_TOOLBAR_NOTIF_AREA, WinTCToolbarNotifArea))
GType wintc_toolbar_notif_area_get_type(void) G_GNUC_CONST;
#endif

View File

@@ -144,7 +144,7 @@ static void wintc_notification_volume_constructed(
// Connect up to the notification icon widget
//
volume->popup_volmgmt =
wintc_dpa_create_popup(behaviour->widget_notif);
wintc_dpa_create_popup(behaviour->widget_notif, FALSE);
volume->box_container = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
volume->check_mute = gtk_check_button_new_with_label("Mute");

View File

@@ -0,0 +1,45 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc-comgtk.h>
#include "../toolbar.h"
#include "taskbuttonbar.h"
#include "toolbar.h"
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCToolbarTaskButtonsClass
{
WinTCTaskbandToolbarClass __parent__;
};
struct _WinTCToolbarTaskButtons
{
WinTCTaskbandToolbar __parent__;
};
//
// GTK TYPE DEFINITION & CTORS
//
G_DEFINE_TYPE(
WinTCToolbarTaskButtons,
wintc_toolbar_task_buttons,
TYPE_WINTC_TASKBAND_TOOLBAR
)
static void wintc_toolbar_task_buttons_class_init(
WINTC_UNUSED(WinTCToolbarTaskButtonsClass* klass)
) {}
static void wintc_toolbar_task_buttons_init(
WinTCToolbarTaskButtons* self
)
{
WinTCTaskbandToolbar* toolbar = WINTC_TASKBAND_TOOLBAR(self);
// Create root widget
//
toolbar->widget_root = taskbutton_bar_new();
}

View File

@@ -0,0 +1,23 @@
#ifndef __TOOLBAR_TASK_BUTTONS_H__
#define __TOOLBAR_TASK_BUTTONS_H__
#include <glib.h>
#include <gtk/gtk.h>
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCToolbarTaskButtonsClass WinTCToolbarTaskButtonsClass;
typedef struct _WinTCToolbarTaskButtons WinTCToolbarTaskButtons;
#define TYPE_WINTC_TOOLBAR_TASK_BUTTONS (wintc_toolbar_task_buttons_get_type())
#define WINTC_TOOLBAR_TASK_BUTTONS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_WINTC_TOOLBAR_TASK_BUTTONS, WinTCToolbarTaskButtons))
#define WINTC_TOOLBAR_TASK_BUTTONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_WINTC_TOOLBAR_TASK_BUTTONS, WinTCToolbarTaskButtonsClass))
#define IS_WINTC_TOOLBAR_TASK_BUTTONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_WINTC_TOOLBAR_TASK_BUTTONS))
#define IS_WINTC_TOOLBAR_TASK_BUTTONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_WINTC_TOOLBAR_TASK_BUTTONS))
#define WINTC_TOOLBAR_TASK_BUTTONS_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_WINTC_TOOLBAR_TASK_BUTTONS, WinTCToolbarTaskButtons))
GType wintc_toolbar_task_buttons_get_type(void) G_GNUC_CONST;
#endif

View File

@@ -0,0 +1,94 @@
#include <glib.h>
#include <gtk/gtk.h>
#include "toolbar.h"
//
// PRIVATE ENUMS
//
enum
{
PROP_ROOT_WIDGET = 1
};
//
// FORWARD DECLARATIONS
//
static void wintc_taskband_toolbar_get_property(
GObject* object,
guint prop_id,
GValue* value,
GParamSpec* pspec
);
//
// GTK TYPE DEFINITIONS & CTORS
//
G_DEFINE_TYPE(
WinTCTaskbandToolbar,
wintc_taskband_toolbar,
G_TYPE_OBJECT
)
static void wintc_taskband_toolbar_class_init(
WinTCTaskbandToolbarClass* klass
)
{
GObjectClass* object_class = G_OBJECT_CLASS(klass);
object_class->get_property = wintc_taskband_toolbar_get_property;
g_object_class_install_property(
object_class,
PROP_ROOT_WIDGET,
g_param_spec_object(
"root-widget",
"RootWidget",
"The GtkWidget that is the root of the toolbar.",
GTK_TYPE_WIDGET,
G_PARAM_READABLE
)
);
}
static void wintc_taskband_toolbar_init(
WinTCTaskbandToolbar* self
)
{
self->widget_root = NULL;
}
//
// PRIVATE FUNCTIONS
//
GtkWidget* wintc_taskband_toolbar_get_root_widget(
WinTCTaskbandToolbar* toolbar
)
{
return toolbar->widget_root;
}
//
// CLASS VIRTUAL METHODS
//
static void wintc_taskband_toolbar_get_property(
GObject* object,
guint prop_id,
GValue* value,
GParamSpec* pspec
)
{
WinTCTaskbandToolbar* toolbar =
WINTC_TASKBAND_TOOLBAR(object);
switch (prop_id)
{
case PROP_ROOT_WIDGET:
g_value_set_object(value, toolbar->widget_root);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}

View File

@@ -0,0 +1,38 @@
#ifndef __TOOLBAR_H__
#define __TOOLBAR_H__
#include <glib.h>
#include <gtk/gtk.h>
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCTaskbandToolbarClass
{
GObjectClass __parent__;
} WinTCTaskbandToolbarClass;
typedef struct _WinTCTaskbandToolbar
{
GObject __parent__;
GtkWidget* widget_root;
} WinTCTaskbandToolbar;
#define TYPE_WINTC_TASKBAND_TOOLBAR (wintc_taskband_toolbar_get_type())
#define WINTC_TASKBAND_TOOLBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_WINTC_TASKBAND_TOOLBAR, WinTCTaskbandToolbar))
#define WINTC_TASKBAND_TOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_WINTC_TASKBAND_TOOLBAR, WinTCTaskbandToolbarClass))
#define IS_WINTC_TASKBAND_TOOLBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_WINTC_TASKBAND_TOOLBAR))
#define IS_WINTC_TASKBAND_TOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_WINTC_TASKBAND_TOOLBAR))
#define WINTC_TASKBAND_TOOLBAR_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_WINTC_TASKBAND_TOOLBAR, WinTCTaskbandToolbar))
GType wintc_taskband_toolbar_get_type(void) G_GNUC_CONST;
//
// PUBLIC FUNCTIONS
//
GtkWidget* wintc_taskband_toolbar_get_root_widget(
WinTCTaskbandToolbar* toolbar
);
#endif

View File

@@ -5,24 +5,57 @@
#include <wintc-shelldpa.h>
#include "application.h"
#include "toolbar.h"
#include "window.h"
#include "start/startbutton.h"
#include "systray/notifarea.h"
#include "taskbuttons/taskbuttonbar.h"
#include "taskbuttons/windowmonitor.h"
#include "start/toolbar.h"
#include "systray/toolbar.h"
#include "taskbuttons/toolbar.h"
#define TASKBAND_HEIGHT 30
//
// PRIVATE ENUMS
//
typedef enum
{
WINTC_TASKBAND_TOOLBAR_START,
WINTC_TASKBAND_TOOLBAR_QUICK_ACCESS,
WINTC_TASKBAND_TOOLBAR_PRE_BUTTONS,
WINTC_TASKBAND_TOOLBAR_BUTTONS,
WINTC_TASKBAND_TOOLBAR_POST_BUTTONS,
WINTC_TASKBAND_TOOLBAR_NOTIFICATION_AREA
} WinTCTaskbandToolbarId;
//
// FORWARD DECLARATIONS
//
static void wintc_taskband_window_create_toolbar(
WinTCTaskbandWindow* taskband,
GType toolbar_type,
gboolean expand
);
static gboolean on_window_map_event(
GtkWidget* self,
GdkEventAny* event,
gpointer user_data
);
//
// STATIC DATA
//
static const WinTCTaskbandToolbarId s_layout[] = {
WINTC_TASKBAND_TOOLBAR_START,
WINTC_TASKBAND_TOOLBAR_QUICK_ACCESS,
WINTC_TASKBAND_TOOLBAR_PRE_BUTTONS,
WINTC_TASKBAND_TOOLBAR_BUTTONS,
WINTC_TASKBAND_TOOLBAR_POST_BUTTONS,
WINTC_TASKBAND_TOOLBAR_NOTIFICATION_AREA
};
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCTaskbandWindowPrivate
{
GtkWidget* main_box;
GtkWidget* notification_area;
GtkWidget* start_button;
GtkWidget* taskbuttons;
};
struct _WinTCTaskbandWindowClass
{
GtkApplicationWindowClass __parent__;
@@ -32,17 +65,20 @@ struct _WinTCTaskbandWindow
{
GtkApplicationWindow __parent__;
WinTCTaskbandWindowPrivate* priv;
GtkWidget* main_box;
GtkWidget* notification_area;
GtkWidget* start_button;
GtkWidget* taskbuttons;
};
//
// GTK TYPE DEFINITION & CTORS
//
G_DEFINE_TYPE_WITH_CODE(
G_DEFINE_TYPE(
WinTCTaskbandWindow,
wintc_taskband_window,
GTK_TYPE_APPLICATION_WINDOW,
G_ADD_PRIVATE(WinTCTaskbandWindow)
GTK_TYPE_APPLICATION_WINDOW
)
static void wintc_taskband_window_class_init(
@@ -53,8 +89,6 @@ static void wintc_taskband_window_init(
WinTCTaskbandWindow* self
)
{
self->priv = wintc_taskband_window_get_instance_private(self);
//
// WINDOW SETUP
//
@@ -63,71 +97,27 @@ static void wintc_taskband_window_init(
"wintc-taskband"
);
// FIXME: This is obviously hard coded rubbish!
//
gtk_widget_set_size_request(GTK_WIDGET(self), -1, TASKBAND_HEIGHT);
wintc_anchor_taskband_to_bottom(GTK_WINDOW(self));
//
// SET UP CHILDREN IN HERE
// FIXME: Tidy all this stuff up big time! Taskband shouldn't know about
// how stuff is built, just ask for a Start button, a taskbar, and
// systray -- no implementation details!!
//
// Create main container box
//
self->priv->main_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
self->main_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_container_add(
GTK_CONTAINER(self),
self->priv->main_box
self->main_box
);
// Create Start button and menu
// Connect to map-event signal to spawn toolbars once the window opens
//
GtkCssProvider* css_start = gtk_css_provider_new();
gtk_css_provider_load_from_resource(
css_start,
"/uk/oddmatics/wintc/taskband/start-menu.css"
);
gtk_style_context_add_provider_for_screen(
gdk_screen_get_default(),
GTK_STYLE_PROVIDER(css_start),
GTK_STYLE_PROVIDER_PRIORITY_FALLBACK
);
self->priv->start_button = start_button_new();
gtk_box_pack_start(
GTK_BOX(self->priv->main_box),
self->priv->start_button,
FALSE,
FALSE,
0
);
// Create task buttons
//
self->priv->taskbuttons = taskbutton_bar_new();
gtk_box_pack_start(
GTK_BOX(self->priv->main_box),
self->priv->taskbuttons,
TRUE,
TRUE,
0
);
// Create notification area
//
self->priv->notification_area = notification_area_new();
gtk_box_pack_end(
GTK_BOX(self->priv->main_box),
self->priv->notification_area,
FALSE,
FALSE,
0
g_signal_connect(
self,
"map-event",
G_CALLBACK(on_window_map_event),
NULL
);
}
@@ -150,3 +140,81 @@ GtkWidget* wintc_taskband_window_new(
)
);
}
//
// PRIVATE FUNCTIONS
//
static void wintc_taskband_window_create_toolbar(
WinTCTaskbandWindow* taskband,
GType toolbar_type,
gboolean expand
)
{
WinTCTaskbandToolbar* toolbar = g_object_new(toolbar_type, NULL);
GtkWidget* root = wintc_taskband_toolbar_get_root_widget(
toolbar
);
gtk_box_pack_start(
GTK_BOX(taskband->main_box),
root,
expand,
expand,
0
);
gtk_widget_show_all(root);
}
//
// CALLBACKS
//
static gboolean on_window_map_event(
GtkWidget* self,
WINTC_UNUSED(GdkEventAny* event),
WINTC_UNUSED(gpointer user_data)
)
{
WinTCTaskbandWindow* taskband = WINTC_TASKBAND_WINDOW(self);
// Spawn toolbars
//
for (guint i = 0; i < G_N_ELEMENTS(s_layout); i++)
{
switch (s_layout[i])
{
case WINTC_TASKBAND_TOOLBAR_START:
wintc_taskband_window_create_toolbar(
taskband,
TYPE_WINTC_TOOLBAR_START,
FALSE
);
break;
case WINTC_TASKBAND_TOOLBAR_BUTTONS:
wintc_taskband_window_create_toolbar(
taskband,
TYPE_WINTC_TOOLBAR_TASK_BUTTONS,
TRUE
);
break;
case WINTC_TASKBAND_TOOLBAR_NOTIFICATION_AREA:
wintc_taskband_window_create_toolbar(
taskband,
TYPE_WINTC_TOOLBAR_NOTIF_AREA,
FALSE
);
break;
case WINTC_TASKBAND_TOOLBAR_QUICK_ACCESS:
case WINTC_TASKBAND_TOOLBAR_PRE_BUTTONS:
case WINTC_TASKBAND_TOOLBAR_POST_BUTTONS:
WINTC_LOG_DEBUG("Not implemented toolbar: %d", s_layout[i]);
break;
}
}
return TRUE;
}

View File

@@ -9,7 +9,6 @@
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCTaskbandWindowPrivate WinTCTaskbandWindowPrivate;
typedef struct _WinTCTaskbandWindowClass WinTCTaskbandWindowClass;
typedef struct _WinTCTaskbandWindow WinTCTaskbandWindow;
@@ -30,3 +29,4 @@ GtkWidget* wintc_taskband_window_new(
);
#endif

View File

@@ -10,7 +10,7 @@
//
// START BUTTON
//
button.xp-start-button
button.wintc-start-button
{
// HACK: Slight hack going on here - in Windows XP, the window buttons has a margin
// either side of it, however it doesn't seem like the custom widget in XFCE
@@ -50,7 +50,7 @@ button.xp-start-button
@include __wintc_apply_props($start_button_press_styles);
}
@at-root .xp-flag
@at-root .wintc-flag
{
@include __wintc_apply_props_excluding(
$start_flag_styles,
@@ -58,8 +58,8 @@ button.xp-start-button
"min-width"
);
min-height: $start_flag_size;
min-width: $start_flag_size;
min-height: $start_flag_height;
min-width: $start_flag_width;
}
// The Start button contains both 'Start' and 'start' labels, so that themes can
@@ -95,7 +95,7 @@ button.xp-start-button
//
// START MENU
//
window.csd.xp-start-menu // Specificity hack -_-
window.csd.wintc-personal-menu // Specificity hack -_-
{
@include __wintc_apply_props($start_menu_styles);
@@ -174,7 +174,7 @@ window.csd.xp-start-menu // Specificity hack -_-
}
}
@at-root .xp-start-userpane
@at-root .start-userpane
{
@include __wintc_apply_props($start_menu_horz_userpane_styles);
@@ -201,7 +201,7 @@ window.csd.xp-start-menu // Specificity hack -_-
}
}
@at-root .xp-start-vuserpane
@at-root .start-vuserpane
{
@include __wintc_apply_props($start_menu_vert_userpane_styles);
@@ -211,7 +211,7 @@ window.csd.xp-start-menu // Specificity hack -_-
}
}
@at-root .xp-start-programs-column
@at-root .start-programs-column
{
@include __wintc_apply_props($start_menu_programs_column_styles);
@@ -274,7 +274,7 @@ window.csd.xp-start-menu // Specificity hack -_-
);
}
@at-root .xp-start-default-item
@at-root .start-default-item
{
@include __wintc_apply_props(
$start_menu_programs_menuitem_mime_styles
@@ -328,21 +328,21 @@ window.csd.xp-start-menu // Specificity hack -_-
margin: 0px;
}
menuitem.xp-start-all-programs
menuitem.start-all-programs
{
@include __wintc_apply_props_not_in_category(
$start_menu_allprograms_menuitem_styles,
font
);
min-height: $start_menu_allprograms_height;
> box
{
@include __wintc_apply_props_for_category(
$start_menu_allprograms_menuitem_styles,
font
);
min-height: $start_menu_allprograms_height;
}
.arrow
@@ -374,7 +374,7 @@ window.csd.xp-start-menu // Specificity hack -_-
}
}
@at-root .xp-start-places-column
@at-root .start-places-column
{
@include __wintc_apply_props($start_menu_places_column_styles);
@@ -393,7 +393,7 @@ window.csd.xp-start-menu // Specificity hack -_-
);
}
&.significant
&.significant > box label
{
@include __wintc_apply_props($start_menu_places_menuitem_top_styles);
}
@@ -411,7 +411,7 @@ window.csd.xp-start-menu // Specificity hack -_-
}
}
@at-root .xp-start-logoffpane
@at-root .start-logoffpane
{
@include __wintc_apply_props($start_menu_logoff_pane_styles);

View File

@@ -7,7 +7,8 @@
* Author(s): Rory Fewell <roryf@oddmatics.uk>
*/
$start_flag_size: 16px !default;
$start_flag_height: 16px !default;
$start_flag_width: 16px !default;
$start_text_case: upper !default;
$start_menu_allprograms_height: 30px !default;
@@ -360,7 +361,7 @@ $start_menu_allprograms_separator_styles:
$start_menu_allprograms_separator_styles,
true,
margin,
20,
4,
undefined,
undefined,
undefined

View File

@@ -7,7 +7,8 @@
* Author(s): Rory Fewell <roryf@oddmatics.uk>
*/
$start_flag_size: 20px;
$start_flag_height: 20px;
$start_flag_width: 20px;
$start_text_case: lower;
$start_menu_allprograms_height: 24px;
@@ -478,7 +479,7 @@ $start_menu_places_column_styles:
padding,
2,
2,
undefined,
5,
5
);
$start_menu_places_column_styles:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -7,7 +7,8 @@
* Author(s): Rory Fewell <roryf@oddmatics.uk>
*/
$start_flag_size: 21px;
$start_flag_height: 18px;
$start_flag_width: 21px;
$start_menu_allprograms_arrow_width: 24px;