From 9585f4b3bee8a5bc01dd11bf439b4c4dc8a054df Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 17 Mar 2008 13:31:17 -0400 Subject: [PATCH] xwm: implement lucca_window_set_states --- xwm/lucca-display.h | 3 +++ xwm/lucca-window.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++ xwm/test/test.c | 3 +++ xwm/test/test.py | 24 +++++++++++++++++++ 4 files changed, 97 insertions(+) diff --git a/xwm/lucca-display.h b/xwm/lucca-display.h index b873f88..a0b31f8 100644 --- a/xwm/lucca-display.h +++ b/xwm/lucca-display.h @@ -130,6 +130,9 @@ void lucca_window_get_geometry_hints(LuccaWindow* window, GdkGeometry* geometry, /* lucca_window_get_requested_states: gets the set of requested states for the window */ LuccaState lucca_window_get_requested_states(LuccaWindow* window); +/* lucca_window_set_states: set the "state" of the window */ +void lucca_window_set_states(LuccaWindow* window, LuccaState states); + /* lucca_window_configure: map a window with the specified parent, size, and position or hide the window */ void lucca_window_configure(LuccaWindow* window, GdkWindow* parent, gint x, gint y, gint width, gint height, gboolean visible); diff --git a/xwm/lucca-window.c b/xwm/lucca-window.c index 38b61c0..7986727 100644 --- a/xwm/lucca-window.c +++ b/xwm/lucca-window.c @@ -29,9 +29,13 @@ OTHER DEALINGS IN THE SOFTWARE. static GObjectClass* parent_class = NULL; static GData* state_atom_constants; +static GHashTable* state_constant_atoms; static GData* type_atom_constants; +GdkAtom netwm_state; +GdkAtom gdkatom_atom; + /* property id's */ enum { PROP_VALID=1, @@ -266,6 +270,20 @@ static void lucca_window_class_init(gpointer g_class, gpointer class_data) { g_datalist_set_data(&state_atom_constants, "_NET_WM_STATE_BELOW", GINT_TO_POINTER(LUCCA_STATE_BELOW)); g_datalist_set_data(&state_atom_constants, "_NET_WM_STATE_DEMANDS_ATTENTION", GINT_TO_POINTER(LUCCA_STATE_DEMANDS_ATTENTION)); + state_constant_atoms = g_hash_table_new(g_direct_hash, g_direct_equal); + g_hash_table_insert(state_constant_atoms, GINT_TO_POINTER(LUCCA_STATE_MODAL), "_NET_WM_STATE_MODAL"); + g_hash_table_insert(state_constant_atoms, GINT_TO_POINTER(LUCCA_STATE_STICKY), "_NET_WM_STATE_STICKY"); + g_hash_table_insert(state_constant_atoms, GINT_TO_POINTER(LUCCA_STATE_MAXIMIZED_VIRT), "_NET_WM_STATE_MAXIMIZED_VIRT"); + g_hash_table_insert(state_constant_atoms, GINT_TO_POINTER(LUCCA_STATE_MAXIMIZED_HORZ), "_NET_WM_STATE_MAXIMIZED_HORZ"); + g_hash_table_insert(state_constant_atoms, GINT_TO_POINTER(LUCCA_STATE_SHADED), "_NET_WM_STATE_SHADED"); + g_hash_table_insert(state_constant_atoms, GINT_TO_POINTER(LUCCA_STATE_SKIP_TASKBAR), "_NET_WM_STATE_SKIP_TASKBAR"); + g_hash_table_insert(state_constant_atoms, GINT_TO_POINTER(LUCCA_STATE_SKIP_PAGER), "_NET_WM_SKIP_PAGER"); + g_hash_table_insert(state_constant_atoms, GINT_TO_POINTER(LUCCA_STATE_HIDDEN), "_NET_WM_STATE_HIDDEN"); + g_hash_table_insert(state_constant_atoms, GINT_TO_POINTER(LUCCA_STATE_FULLSCREEN), "_NET_WM_STATE_FULLSCREEN"); + g_hash_table_insert(state_constant_atoms, GINT_TO_POINTER(LUCCA_STATE_ABOVE), "_NET_WM_STATE_ABOVE"); + g_hash_table_insert(state_constant_atoms, GINT_TO_POINTER(LUCCA_STATE_BELOW), "_NET_WM_STATE_BELOW"); + g_hash_table_insert(state_constant_atoms, GINT_TO_POINTER(LUCCA_STATE_DEMANDS_ATTENTION), "_NET_WM_STATE_DEMANDS_ATTENTION"); + g_datalist_init(&type_atom_constants); g_datalist_set_data(&type_atom_constants, "_NET_WM_WINDOW_TYPE_NORMAL", GINT_TO_POINTER(LUCCA_TYPE_NORMAL)); g_datalist_set_data(&type_atom_constants, "_NET_WM_WINDOW_TYPE_DESKTOP", GINT_TO_POINTER(LUCCA_TYPE_DESKTOP)); @@ -280,6 +298,9 @@ static void lucca_window_class_init(gpointer g_class, gpointer class_data) { g_datalist_set_data(&type_atom_constants, "_NET_WM_WINDOW_TYPE_TOOLTIP", GINT_TO_POINTER(LUCCA_TYPE_TOOLTIP)); g_datalist_set_data(&type_atom_constants, "_NET_WM_WINDOW_TYPE_NOTIFICATION", GINT_TO_POINTER(LUCCA_TYPE_NOTIFICATION)); g_datalist_set_data(&type_atom_constants, "_NET_WM_WINDOW_TYPE_DND", GINT_TO_POINTER(LUCCA_TYPE_DND)); + + netwm_state = gdk_atom_intern("_NET_WM_STATE", FALSE); + gdkatom_atom = gdk_atom_intern("ATOM", FALSE); } GType lucca_window_get_type() { @@ -1395,3 +1416,49 @@ void lucca_window_netwmstate_request(LuccaWindow* window, XClientMessageEvent* e g_signal_emit(window, LUCCA_WINDOW_GET_CLASS(window)->state_request_signal_id, 0, (gint)requested_states); } +void lucca_window_set_states(LuccaWindow* window, LuccaState states) { + gulong* state_list; + LuccaState temp_states; + guint state_count = 0; + gint i, j; + + if (states == window->netwm_states) + return; + + /* count the states that are set */ + temp_states = states; + while (temp_states != 0) { + state_count += temp_states&1; + temp_states >>= 1; + } + + /* allocate memory for a list of states */ + state_list = g_malloc(sizeof(gulong) * state_count); + + /* add each state to the list */ + j=0; i=1; + while (j < state_count) { + if (states & i) { + state_list[j] = (gulong)gdk_atom_intern(g_hash_table_lookup(state_constant_atoms, GINT_TO_POINTER(i)), FALSE); + + j++; + } + + i <<= 1; + } + + /* set the _NET_WM_STATE property */ + gdk_property_change(window->window, /* window */ + netwm_state, /* property */ + gdkatom_atom, /* type */ + 32, /* format */ + GDK_PROP_MODE_REPLACE, /* mode */ + (guchar*)state_list, /* data */ + state_count /* nelements */ + ); + + window->netwm_states = states; + + g_free(state_list); +} + diff --git a/xwm/test/test.c b/xwm/test/test.c index 99387b9..5fe5107 100644 --- a/xwm/test/test.c +++ b/xwm/test/test.c @@ -172,6 +172,9 @@ gboolean on_input(GIOChannel* source, GIOCondition condition, gpointer data) { else if (g_ascii_strcasecmp(input_words[0], "get_requested_states") == 0) { g_print("%i\n", lucca_window_get_requested_states(LUCCA_WINDOW(strtol(input_words[1]+2, NULL, 16)))); } + else if (g_ascii_strcasecmp(input_words[0], "set_states") == 0) { + lucca_window_set_states(LUCCA_WINDOW(strtol(input_words[1]+2, NULL, 16)), (LuccaState)strtol(input_words[2], NULL, 10)); + } else if (g_ascii_strcasecmp(input_words[0], "configure") == 0) { lucca_window_configure(LUCCA_WINDOW(strtol(input_words[1]+2, NULL, 16)), GDK_WINDOW(strtol(input_words[2]+2, NULL, 16)), strtol(input_words[3], NULL, 10), strtol(input_words[4], NULL, 10), strtol(input_words[5], NULL, 10), strtol(input_words[6], NULL, 10), strtol(input_words[7], NULL, 10)); } diff --git a/xwm/test/test.py b/xwm/test/test.py index 9e3e2de..032d15b 100644 --- a/xwm/test/test.py +++ b/xwm/test/test.py @@ -162,6 +162,30 @@ def nongtk_thread(): line = getline() assert(line == ['state-request', luccawindow1, '256']) + + fullscreen_mutex = thread.allocate_lock() + fullscreen_mutex.acquire() + def set_state_event(): + def timeout(): + logfile.write("ERROR: timeout waiting for state change event\n") + tests_failed = True + thread.interrupt_main() + fullscreen_mutex.release() + + source = gobject.timeout_add(5000, timeout) + + def on_fullscreen(widget, event): + logfile.write(":got state change event\n") + + gobject.source_remove(source) + fullscreen_mutex.release() + + gtkwindow1.connect('window-state-event', on_fullscreen) + + do_in_gtk_thread(set_state_event) + + send('set_states %s 256' % luccawindow1) + fullscreen_mutex.acquire() #withdraw the existing window def withdraw_window(): -- 2.11.4.GIT