Skip to content

Commit

Permalink
Add initial shell based on GNOME Control Center code.
Browse files Browse the repository at this point in the history
  • Loading branch information
TheWiseNoob committed Apr 16, 2024
1 parent 5b8a96f commit 5a90c7e
Show file tree
Hide file tree
Showing 5 changed files with 441 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ executable(
'app.c',
'sidebar.c',
'content.c',
'panel.c',
'shell.c',
'appwin.c',
'main.c',
omp_resources,
Expand Down
202 changes: 202 additions & 0 deletions src/panel.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
#include "panel.h"

#include <stdio.h>
#include <stdlib.h>

#include <gio/gio.h>
#include <gtk/gtk.h>

typedef struct {
OMPShell* shell;
GCancellable* cancellable;

gchar* subpage;
} OMPPanelPrivate;

G_DEFINE_ABSTRACT_TYPE_WITH_CODE (
OMPPanel, omp_panel, ADW_TYPE_NAVIGATION_PAGE, G_ADD_PRIVATE (OMPPanel)
)

enum { PROP_0, PROP_SHELL, PROP_PARAMETERS, PROP_SUBPAGE, N_PROPS };

static GParamSpec* properties[N_PROPS];

/* GtkBuildable interface */

/* GObject overrides */

static void
omp_panel_set_property (
GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec
)
{
OMPPanelPrivate* priv = omp_panel_get_instance_private (OMP_PANEL (object));

switch (prop_id) {
case PROP_SHELL:
/* construct only property */
priv->shell = g_value_get_object (value);
break;

case PROP_PARAMETERS: {
g_autoptr (GVariant) v = NULL;
GVariant* parameters;
gsize n_parameters;

parameters = g_value_get_variant (value);

if (parameters == NULL)
return;

n_parameters = g_variant_n_children (parameters);
if (n_parameters == 0)
return;

g_variant_get_child (parameters, 0, "v", &v);

if (g_variant_is_of_type (v, G_VARIANT_TYPE_STRING)) {
g_set_str (&priv->subpage, g_variant_get_string (v, NULL));
g_object_notify_by_pspec (object, properties[PROP_SUBPAGE]);
}
else if (!g_variant_is_of_type (v, G_VARIANT_TYPE_DICTIONARY))
g_warning (
"Wrong type for the first argument GVariant, expected "
"'a{sv}' but got '%s'",
(gchar*)g_variant_get_type (v)
);
else if (g_variant_n_children (v) > 0)
g_warning ("Ignoring additional flags");

if (n_parameters > 1)
g_warning ("Ignoring additional parameters");

break;
}

default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}

static void
omp_panel_get_property (
GObject* object, guint prop_id, GValue* value, GParamSpec* pspec
)
{
OMPPanelPrivate* priv = omp_panel_get_instance_private (OMP_PANEL (object));

switch (prop_id) {
case PROP_SHELL:
g_value_set_object (value, priv->shell);
break;

case PROP_SUBPAGE:
g_value_set_string (value, priv->subpage);
break;

default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}

static void
omp_panel_finalize (GObject* object)
{
OMPPanelPrivate* priv = omp_panel_get_instance_private (OMP_PANEL (object));

g_cancellable_cancel (priv->cancellable);
g_clear_object (&priv->cancellable);
g_clear_pointer (&priv->subpage, g_free);

G_OBJECT_CLASS (omp_panel_parent_class)->finalize (object);
}

static void
omp_panel_class_init (OMPPanelClass* klass)
{
GObjectClass* object_class = G_OBJECT_CLASS (klass);

object_class->get_property = omp_panel_get_property;
object_class->set_property = omp_panel_set_property;
object_class->finalize = omp_panel_finalize;

properties[PROP_SHELL] = g_param_spec_object (
"shell", "Shell", "Shell the Panel resides in", OMP_TYPE_SHELL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS
);

properties[PROP_PARAMETERS] = g_param_spec_variant (
"parameters", "Structured parameters",
"Additional parameters passed externally (ie. command line, D-Bus "
"activation)",
G_VARIANT_TYPE ("av"), NULL, G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS
);

properties[PROP_SUBPAGE] = g_param_spec_string (
"subpage", "Subpage parameters",
"Additional parameter extracted from the parameters property to launch "
"a panel subpage",
NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS
);

g_object_class_install_properties (object_class, N_PROPS, properties);
}

static void
omp_panel_init (OMPPanel* panel)
{
}

/**
* omp_panel_get_shell:
* @panel: A #OMPPanel
*
* Get the shell that the panel resides in
*
* Returns: a #OMPShell
*/
OMPShell*
omp_panel_get_shell (OMPPanel* panel)
{
OMPPanelPrivate* priv;

g_return_val_if_fail (OMP_IS_PANEL (panel), NULL);

priv = omp_panel_get_instance_private (panel);

return priv->shell;
}

const gchar*
omp_panel_get_help_uri (OMPPanel* panel)
{
OMPPanelClass* class = OMP_PANEL_GET_CLASS (panel);

if (class->get_help_uri)
return class->get_help_uri (panel);

return NULL;
}

GCancellable*
omp_panel_get_cancellable (OMPPanel* panel)
{
OMPPanelPrivate* priv = omp_panel_get_instance_private (panel);

g_return_val_if_fail (OMP_IS_PANEL (panel), NULL);

if (priv->cancellable == NULL)
priv->cancellable = g_cancellable_new ();

return priv->cancellable;
}

void
omp_panel_deactivate (OMPPanel* panel)
{
OMPPanelPrivate* priv = omp_panel_get_instance_private (panel);

g_cancellable_cancel (priv->cancellable);
}
71 changes: 71 additions & 0 deletions src/panel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#pragma once

#include <adwaita.h>

/**
* Utility macro used to register panels
*
* use: OMP_PANEL_REGISTER (PluginName, plugin_name)
*/
#define OMP_PANEL_REGISTER(PluginName, plugin_name) \
G_DEFINE_TYPE (PluginName, plugin_name, OMP_TYPE_PANEL)

/**
* OMPPanelStaticInitFunc:
*
* Function that statically allocates resources and initializes
* any data that the panel will make use of during runtime.
*
* If panels represent hardware that can potentially not exist,
* e.g. the Wi-Fi panel, these panels can use this function to
* show or hide themselves without needing to have an instance
* created and running.
*/
typedef void (*OMPPanelStaticInitFunc) (void);

#define OMP_TYPE_PANEL (omp_panel_get_type ())
G_DECLARE_DERIVABLE_TYPE (OMPPanel, omp_panel, OMP, PANEL, AdwNavigationPage)

/**
* OMPPanelVisibility:
*
* @OMP_PANEL_HIDDEN: Panel is hidden from search and sidebar, and not
* reachable.
* @OMP_PANEL_VISIBLE_IN_SEARCH: Panel is hidden from main view, but can be
* aompessed from search.
* @OMP_PANEL_VISIBLE: Panel is visible everywhere.
*/
typedef enum {
OMP_PANEL_HIDDEN,
OMP_PANEL_VISIBLE_IN_SEARCH,
OMP_PANEL_VISIBLE,
} OMPPanelVisibility;

/* omp-shell.h requires OMPPanel, so make sure it is defined first */
#include "shell.h"

G_BEGIN_DECLS

/**
* OMPPanelClass:
*
* The contents of this struct are private and should not be aompessed directly.
*/
struct _OMPPanelClass {
/*< private >*/
AdwNavigationPageClass parent_class;

const gchar* (*get_help_uri) (OMPPanel* panel);
};

OMPShell* omp_panel_get_shell (OMPPanel* panel);

GPermission* omp_panel_get_permission (OMPPanel* panel);

const gchar* omp_panel_get_help_uri (OMPPanel* panel);

GCancellable* omp_panel_get_cancellable (OMPPanel* panel);

void omp_panel_deactivate (OMPPanel* panel);

G_END_DECLS
Loading

0 comments on commit 5a90c7e

Please sign in to comment.