Reimplement the wm module in C

The wm module in sugar-toolkit-gtk3 has been reimplemented
in C and made available through introspection. The same was
hard to achieve directly using the Gdk API.

We can drop wm.py and the wrapper around gdk_property_change.

Signed-off-by: Daniel Narvaez <dwnarvaez@gmail.com>
Acked-by: Simon Schampijer <simon@laptop.org>
This commit is contained in:
Daniel Narvaez 2012-08-24 12:23:17 +02:00 committed by Simon Schampijer
parent a14574c666
commit 4cc6967c8d
7 changed files with 134 additions and 198 deletions

View File

@ -9,8 +9,7 @@ sugar_PYTHON = \
network.py \ network.py \
profile.py \ profile.py \
session.py \ session.py \
util.py \ util.py
wm.py
lib_LTLIBRARIES = libsugarext.la lib_LTLIBRARIES = libsugarext.la
@ -36,8 +35,6 @@ libsugarext_la_SOURCES = \
eggsmclient.h \ eggsmclient.h \
eggsmclient-private.h \ eggsmclient-private.h \
eggsmclient-xsmp.c \ eggsmclient-xsmp.c \
gdk-wrapper.c \
gdk-wrapper.h \
gsm-app.c \ gsm-app.c \
gsm-app.h \ gsm-app.h \
gsm-client.c \ gsm-client.c \
@ -51,7 +48,9 @@ libsugarext_la_SOURCES = \
sugar-grid.c \ sugar-grid.c \
sugar-grid.h \ sugar-grid.h \
sugar-key-grabber.c \ sugar-key-grabber.c \
sugar-key-grabber.h sugar-key-grabber.h \
sugar-wm.c \
sugar-wm.h
sugar_LTLIBRARIES = _sugarbaseext.la sugar_LTLIBRARIES = _sugarbaseext.la
@ -112,8 +111,7 @@ INTROSPECTION_GIRS = SugarExt-1.0.gir
INTROSPECTION_SCANNER_ARGS = --identifier-prefix=Sugar --symbol-prefix=sugar \ INTROSPECTION_SCANNER_ARGS = --identifier-prefix=Sugar --symbol-prefix=sugar \
--identifier-prefix=EggSM --symbol-prefix=egg_sm \ --identifier-prefix=EggSM --symbol-prefix=egg_sm \
--identifier-prefix=Gsm --symbol-prefix=gsm \ --identifier-prefix=Gsm --symbol-prefix=gsm \
--identifier-prefix=Acme --symbol-prefix=acme \ --identifier-prefix=Acme --symbol-prefix=acme
--identifier-prefix=GdkWrapper --symbol-prefix=gdk_wrapper
SugarExt_1_0_gir_LIBS = libsugarext.la SugarExt_1_0_gir_LIBS = libsugarext.la
SugarExt_1_0_gir_FILES = \ SugarExt_1_0_gir_FILES = \
acme-volume.c \ acme-volume.c \
@ -130,8 +128,8 @@ SugarExt_1_0_gir_FILES = \
sugar-key-grabber.h \ sugar-key-grabber.h \
sugar-grid.c \ sugar-grid.c \
sugar-grid.h \ sugar-grid.h \
gdk-wrapper.c \ sugar-wm.c \
gdk-wrapper.h sugar-wm.h
SugarExt_1_0_gir_INCLUDES = Gtk-3.0 Gdk-3.0 SugarExt_1_0_gir_INCLUDES = Gtk-3.0 Gdk-3.0
SugarExt_1_0_gir_PACKAGES = gtk+-3.0 gdk-3.0 SugarExt_1_0_gir_PACKAGES = gtk+-3.0 gdk-3.0

View File

@ -82,8 +82,7 @@ from sugar3.graphics.alert import Alert
from sugar3.graphics.icon import Icon from sugar3.graphics.icon import Icon
from sugar3.datastore import datastore from sugar3.datastore import datastore
from sugar3.session import XSMPClient from sugar3.session import XSMPClient
from sugar3 import wm from gi.repository import SugarExt
_ = lambda msg: gettext.dgettext('sugar-toolkit', msg) _ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
@ -940,8 +939,9 @@ class Activity(Window, Gtk.Container):
self._complete_close() self._complete_close()
def __realize_cb(self, window): def __realize_cb(self, window):
wm.set_bundle_id(window.get_window(), self.get_bundle_id()) xid = window.get_window().get_xid()
wm.set_activity_id(window.get_window(), str(self._activity_id)) SugarExt.wm_set_bundle_id(xid, self.get_bundle_id())
SugarExt.wm_set_activity_id(xid, str(self._activity_id))
def __delete_event_cb(self, widget, event): def __delete_event_cb(self, widget, event):
self.close() self.close()

View File

@ -1,59 +0,0 @@
/* gdk-wrapper.c
*
* Copyright (C) 1995-2007 Peter Mattis, Spencer Kimball,
* Josh MacDonald, Ryan Lortie
* Copyright (C) 2011 Raul Gutierrez Segales
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
/* Work around introspection unfriendly API in gdk */
#include "gdk-wrapper.h"
#include <string.h>
/**
* gdk_wrapper_property_change:
* @window: a #GdkWindow
* @property: the property to change
* @type: the new type for the property. If @mode is
* %GDK_PROP_MODE_PREPEND or %GDK_PROP_MODE_APPEND, then this
* must match the existing type or an error will occur.
* @format: the new format for the property. If @mode is
* %GDK_PROP_MODE_PREPEND or %GDK_PROP_MODE_APPEND, then this
* must match the existing format or an error will occur.
* @mode: a value describing how the new data is to be combined
* with the current data.
* @data: the data (a <literal>gchar *</literal>)
*
* Changes the contents of a property on a window.
*/
void
gdk_wrapper_property_change (GdkWindow *window,
const gchar *property,
const gchar *type,
gint format,
GdkPropMode mode,
const gchar *data)
{
GdkAtom property_a = gdk_atom_intern (property, FALSE);
GdkAtom type_a = gdk_atom_intern (type, FALSE);
gint nelements = strlen(data);
gdk_property_change (window, property_a, type_a, format, mode,(const guchar *)data,
nelements);
}

View File

@ -1,36 +0,0 @@
/* gdk-wrapper.h
* Copyright (C) 2011 Raul Gutierrez Segales
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __GDK_WRAPPER_H__
#define __GDK_WRAPPER_H__
#include <gdk/gdk.h>
void
gdk_wrapper_property_change (GdkWindow *window,
const gchar *property,
const gchar *type,
gint format,
GdkPropMode mode,
const gchar *data);
#endif /* __GDK_WRAPPER_H__ */

86
src/sugar3/sugar-wm.c Normal file
View File

@ -0,0 +1,86 @@
/*
* Copyright (C) 2012, Daniel Narvaez
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <string.h>
#include <X11/Xatom.h>
#include <gdk/gdkx.h>
#include "sugar-wm.h"
#define MAX_PROPERTY_LEN 1024
static char *
get_property(Window window, const char *name)
{
Display *display;
Atom property;
Atom actual_type;
int actual_format;
unsigned long n_items;
unsigned long bytes_after;
unsigned char *data;
display = gdk_x11_get_default_xdisplay();
property = XInternAtom(display, name, False);
if (XGetWindowProperty(display, window, property, 0, MAX_PROPERTY_LEN,
False, XA_STRING, &actual_type, &actual_format,
&n_items, &bytes_after, &data) != Success) {
return NULL;
}
return (char *)data;
}
static void
set_property(Window window, const char *name, const char *value)
{
Display *display;
Atom property;
display = gdk_x11_get_default_xdisplay();
property = XInternAtom(display, name, False);
XChangeProperty (display, window, property, XA_STRING, 8, PropModeReplace,
(unsigned char *)value, strlen(value));
}
char *
sugar_wm_get_activity_id(Window window)
{
return get_property(window, "_SUGAR_ACTIVITY_ID");
}
char *
sugar_wm_get_bundle_id(Window window)
{
return get_property(window, "_SUGAR_BUNDLE_ID");
}
void
sugar_wm_set_activity_id(Window window, const char *activity_id)
{
set_property(window, "_SUGAR_ACTIVITY_ID", activity_id);
}
void
sugar_wm_set_bundle_id(Window window, const char *bundle_id)
{
set_property(window, "_SUGAR_BUNDLE_ID", bundle_id);
}

37
src/sugar3/sugar-wm.h Normal file
View File

@ -0,0 +1,37 @@
/*
* Copyright (C) 2012, Daniel Narvaez
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __SUGAR_WM_H__
#define __SUGAR_WM_H__
#include <glib.h>
#include <X11/Xlib.h>
G_BEGIN_DECLS
char * sugar_wm_get_activity_id (Window window);
char * sugar_wm_get_bundle_id (Window window);
void sugar_wm_set_activity_id (Window window,
const char *activity_id);
void sugar_wm_set_bundle_id (Window window,
const char *bundle_id);
G_END_DECLS
#endif /* __SUGAR_WM_H__ */

View File

@ -1,90 +0,0 @@
# Copyright (C) 2007, Red Hat, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
"""
UNSTABLE. Used only internally by Activity and jarabe.
"""
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import SugarExt
import logging
def _property_get_trapped(window, prop, prop_type):
Gdk.error_trap_push()
prop_info = window.property_get(prop, prop_type)
# We just log a message
error = Gdk.error_trap_pop()
if error:
logging.debug('Received X Error (%i) while getting '
'a property on a window', error)
return prop_info
def _property_change_trapped(window, prop, prop_type, format, mode, data):
# pylint: disable=W0622
Gdk.error_trap_push()
SugarExt.property_change(window, prop, prop_type, format, mode, data)
error = Gdk.error_trap_pop()
if error:
logging.debug('Received X Error (%i) while setting '
'a property on a window', error)
raise RuntimeError('Received X Error (%i) while setting '
'a property on a window' % error)
def get_activity_id(wnck_window):
window = Gdk.window_foreign_new(wnck_window.get_xid())
prop_info = _property_get_trapped(window, '_SUGAR_ACTIVITY_ID', 'STRING')
if prop_info is None:
return None
else:
return prop_info[2]
def get_bundle_id(wnck_window):
window = Gdk.window_foreign_new(wnck_window.get_xid())
prop_info = _property_get_trapped(window, '_SUGAR_BUNDLE_ID', 'STRING')
if prop_info is None:
return None
else:
return prop_info[2]
def get_sugar_window_type(wnck_window):
window = Gdk.window_foreign_new(wnck_window.get_xid())
prop_info = _property_get_trapped(window, '_SUGAR_WINDOW_TYPE', 'STRING')
if prop_info is None:
return None
else:
return prop_info[2]
def set_activity_id(window, activity_id):
_property_change_trapped(window, '_SUGAR_ACTIVITY_ID', 'STRING', 8,
Gdk.PropMode.REPLACE, activity_id)
def set_bundle_id(window, bundle_id):
_property_change_trapped(window, '_SUGAR_BUNDLE_ID', 'STRING', 8,
Gdk.PropMode.REPLACE, bundle_id)