[IMPORTANT] help with integrating pager



Hi all,

I'm not that good at libtool-stuff, so I need some help at merging the
pager into sawfish (need to adjust the path to client.so *after*
compilation and before/while install).

First grab the pager.jl from the sawfish-pager-0.7 package (see
sourceforge.net), then grab the pager.c attached and place into sawfishs
src/ directory, the last step is to apply the src_mk_patch.

so we compile and install `pager' correctly, but the path to client.so
needs to be adjusted to `$(shell pkg-config --variable=repcommonexecdir
librep)/sawfish/client.so'

or if you know a better way, you're welcome, too :)

Thanks in advance,
Chris
diff --git a/src/Makefile.in b/src/Makefile.in
index b7b2d91..b4edb3d 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -38,9 +38,10 @@ DL_DSTS = sawfish/wm/util/gradient.la sawfish/wm/util/flippers.la \
 	  sawfish/wm/util/play-sample.la
 DL_DIRS = sawfish/wm/util
 
+PAGER_LDFLAGS = $(LDFLAGS) $(srcdir)/src/.libs/client.so
 override CFLAGS := $(CFLAGS) $(REP_CFLAGS) $(IMAGE_CFLAGS) $(X11_CFLAGS) $(ESD_CFLAGS) $(PANGO_CFLAGS)
 
-all : sawfish libclient.o $(DL_OBJS) .libexec gtk-style
+all : sawfish libclient.o $(DL_OBJS) .libexec gtk-style pager
 
 sawfish : $(OBJS) $(LIBOBJS)
 	$(rep_LIBTOOL) --mode=link --tag=CC $(CC) -export-dynamic $(LDFLAGS) \
@@ -62,11 +63,15 @@ client.la : client.lo libclient_.lo
 gtk-style : gtk-style.c
 	$(CC) $(CFLAGS) $(CPPFLAGS) $(GTK_CFLAGS) $(LDFLAGS) -o $@ $< $(GTK_LIBS) $(LIBS)
 
+pager : pager.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(GTK_CFLAGS) $(PAGER_LDFLAGS) -o $@ $< $(GTK_LIBS) $(LIBS)
+
 install : all installdirs
 	for p in sawfish; do \
 	  $(rep_LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)${bindir}; \
 	done
 	$(rep_DL_INSTALL) gtk-style $(DESTDIR)${sawfishexecdir}
+	$(rep_DL_INSTALL) pager $(DESTDIR)${sawfishexecdir}
 	$(foreach x,$(DL_DSTS),\
 	  $(rep_LIBTOOL) --mode=install $(INSTALL_PROGRAM) \
 	  $(notdir $(x)) $(DESTDIR)$(sawfishexecdir)/$(dir $(x));)
@@ -97,7 +102,7 @@ clean :
 distclean: realclean
 
 realclean : clean
-	rm -f .*.d sawfish sawfish-about.jl Makefile gtk-style
+	rm -f .*.d sawfish sawfish-about.jl Makefile gtk-style pager
 	rm -rf .libs
 
 -include $(SRCS:%.c=.%.d) $(DL_SRCS:%.c=.%.d)
/* pager.c -- The display program of sawfish.wm.ext.pager

   Copyright (C) 2009 Christopher Bratusek <zanghar freenet de>
   Copyright (C) 2007 Janek Kozicki <janek_listy wp pl>
   Copyright (C) 2002 Daniel Pfeiffer <occitan esperanto org>
   Copyright (C) 2000 Satyaki Das <satyaki theforce stanford edu>
                      Hakon Alstadheim

   This file is part of sawfish.

   sawfish 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, or (at your option)
   any later version.

   sawfish is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with sawfish; see the file COPYING.   If not, write to
   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/select.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include "libclient.h"

enum { bg, hilit_bg, win, focus_win, win_border, vp_divider, ws_divider, vp_frame };
int hatch = 0;
int xmark = 0;

GdkColor colors[ws_divider+1];
GdkGC *gc[vp_frame+1];
GdkColormap *cmap = NULL;
GdkPixmap *background = NULL;
GdkPixmap *pixmap = NULL;
GtkWidget *drawing_area;
GtkWidget *window;
GdkRectangle update_rect;

/* can read this many chars, truncate beyond */
#define MAXSTRING 2048
char bg_filename[MAXSTRING] = "";


/* can display this many, including all instances of stickies */
#define MAXWINDOWS 1024
struct {
  long id;
  GdkRectangle w, c;		/* window and clip area */
} windows[MAXWINDOWS], *lowest, *w, *dragged_window, *tooltip_window;

int vp_width, vp_height, ws_width, ws_height, width, height;
int offset_x, offset_y;
int show_all_ws, ws_x, ws_y, vp_x, vp_y;
long focus_id;
int mouse_x = -1;
int mouse_y = -1;

gint delete_event( GtkWidget *, GdkEvent *, gpointer );
gint destroy_event( GtkWidget *, GdkEvent *, gpointer );
gint configure_event( GtkWidget *, GdkEvent *, gpointer );
gint leave_notify_event( GtkWidget *, GdkEvent *, gpointer );
gint expose_event( GtkWidget *, GdkEventExpose *, gpointer );
gint button_press_event( GtkWidget *, GdkEventButton *, gpointer );
gint button_release_event( GtkWidget *, GdkEventButton *, gpointer );
gint motion_notify_event( GtkWidget *, GdkEventMotion *, gpointer );

void
wait_stdin( gpointer, gint, GdkInputCondition );

void make_background( void );
void draw_pager( GtkWidget * );
gint draw_tooltip( void );
void parse_stdin( void );
void send_command( char *cmd );

static void wmspec_change_state( gboolean , GdkWindow *, GdkAtom , GdkAtom );


int main( int argc, char *argv[] )
{
  GtkWidget *vbox;

  gtk_init( &argc, &argv );

  if( client_open( NULL ) )
    exit( 1 );
  atexit( client_close );

  window = argc == 2 ?
    gtk_plug_new( strtol( argv[1], NULL, 10 )) :
    gtk_window_new( GTK_WINDOW_TOPLEVEL );
  vbox = gtk_vbox_new( FALSE, 0 );
  gtk_container_add( GTK_CONTAINER( window ), vbox );
  drawing_area = gtk_drawing_area_new();

  /* Get the dimensions and colors of the pager and viewport and focus */
  parse_stdin();

  update_rect.x = update_rect.y = 0;

  gtk_drawing_area_size( GTK_DRAWING_AREA( drawing_area ), width, height );
  gtk_box_pack_start( GTK_BOX( vbox ), drawing_area, FALSE, FALSE, 0 );

  /* Signals to quit */
  gtk_signal_connect( GTK_OBJECT( window ), "delete_event",
		      GTK_SIGNAL_FUNC( delete_event ), NULL );
  gtk_signal_connect( GTK_OBJECT( window ), "destroy",
		      GTK_SIGNAL_FUNC( destroy_event ), NULL );

  /* Wait for input from standard input */
  gdk_input_add( 0, GDK_INPUT_READ,
		 &wait_stdin,
		 drawing_area );

  /* Change the viewport when a button is pressed */
  gtk_signal_connect( GTK_OBJECT( drawing_area ), "motion_notify_event",
		     (GtkSignalFunc) motion_notify_event, NULL );
  gtk_signal_connect( GTK_OBJECT( drawing_area ), "button_press_event",
		     (GtkSignalFunc) button_press_event, NULL );
  gtk_signal_connect( GTK_OBJECT( drawing_area ), "button_release_event",
		     (GtkSignalFunc) button_release_event, NULL );
  gtk_signal_connect( GTK_OBJECT( drawing_area ), "leave_notify_event",
		     (GtkSignalFunc) leave_notify_event, NULL );
  gtk_widget_set_events( drawing_area, GDK_EXPOSURE_MASK
			            | GDK_LEAVE_NOTIFY_MASK
			            | GDK_BUTTON_PRESS_MASK
                                    | GDK_BUTTON_RELEASE_MASK
		                    | GDK_POINTER_MOTION_MASK
		                    | GDK_POINTER_MOTION_HINT_MASK );

  /* Initialize and draw the pixmap */
  gtk_signal_connect( GTK_OBJECT( drawing_area ), "expose_event",
		     (GtkSignalFunc) expose_event, NULL );
  gtk_signal_connect( GTK_OBJECT( drawing_area ), "configure_event",
		     (GtkSignalFunc) configure_event, NULL );

  gtk_widget_show( drawing_area );
  gtk_widget_show( vbox );

  wmspec_change_state(TRUE, window->window,
		  gdk_atom_intern( "_NET_WM_STATE_SKIP_PAGER", FALSE ),
		  gdk_atom_intern( "_NET_WM_STATE_SKIP_TASKBAR", FALSE ));

  gtk_widget_show( window );
  gtk_main();
  return 0;
}

inline void send_command( char *cmd )
{
  int rv;
  client_eval( cmd, NULL, &rv );
}

inline gint find_w( int x, int y ) {
  for( w = windows; w <= lowest; w++ )
    if( w->w.x <= x && w->w.x + w->w.width > x &&
	w->w.y <= y && w->w.y + w->w.height > y )
      return TRUE;
  return FALSE;
}

inline void box( int color, gint filled,
		 gint x, gint y, gint width, gint height )
{
  gdk_draw_rectangle( pixmap, gc[color], filled, x, y, width, height );
}

inline void clipbox( int color, gint filled,
		     gint x, gint y, gint width, gint height,
		     GdkRectangle *c )
{
  if(width < 0 || height < 0)
    return;
  gdk_gc_set_clip_rectangle( gc[color], c );
  gdk_draw_rectangle( pixmap, gc[color], filled, x, y, width, height );
}


gint expose_event( GtkWidget *widget, GdkEventExpose *event, gpointer data )
{
  gdk_draw_pixmap( widget->window,
		  widget->style->fg_gc[GTK_WIDGET_STATE( widget )],
		  pixmap,
		  0, 0, 0, 0,
		  width, height );
  return TRUE;
}

gint leave_notify_event( GtkWidget *widget, GdkEvent *event, gpointer data )
{
  if( !dragged_window ) {
    mouse_x = width;
    mouse_y = height;

    draw_tooltip();
  }
  return TRUE;
}

gint button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer d )
{
  char cmd[64];
  int x, y;

  mouse_x = x = (int) event->x;
  mouse_y = y = (int) event->y;

  if( !(x % ws_width) || !(y % ws_height) ) /* WS border */
    return TRUE;

  /* Button1 changes viewport */
  if( event->button == 1 ) {
    sprintf( cmd, "(pager-goto %ld %d %d)", find_w( x, y ) ? w->id : 0, x, y );
    send_command( cmd );
    draw_tooltip();
  }

  /* Button2 raises/lowers current window */
  else if( event->button == 2 && find_w( x, y ) ) {
    sprintf( cmd, "(pager-change-depth %ld)", w->id );
    send_command( cmd );
    draw_tooltip();
  }

  /* Button3 is for dragging the selected window */
  else if( event->button == 3 && find_w( x, y ) ) {
    draw_tooltip();
    dragged_window = w;

    /* Offset of top left from cursor */
    offset_x = x - w->w.x;
    offset_y = y - w->w.y;
  }
  return TRUE;
}

gint motion_notify_event( GtkWidget *widget, GdkEventMotion *event, gpointer d )
{
  GdkModifierType state;

  if( event->is_hint )
    gdk_window_get_pointer( event->window, &mouse_x, &mouse_y, &state );
  else {
    mouse_x = event->x;
    mouse_y = event->y;
    state = event->state;
  }

  if( dragged_window && state & GDK_BUTTON3_MASK ) {
    char cmd[64];
    sprintf( cmd, "(pager-move-window %ld %d %d %d %d %d %d)",
	     dragged_window->id, mouse_x-offset_x, mouse_y-offset_y,
	     dragged_window->w.width, dragged_window->w.height,
	     mouse_x, mouse_y );
    send_command( cmd );
  } else
    draw_tooltip();

  return TRUE;
}

gint button_release_event( GtkWidget *widget, GdkEventButton *event, gpointer d )
{
  if( dragged_window && event->button == 3 ) {
    int x = (int) event->x;
    int y = (int) event->y;
    char cmd[64];
    sprintf( cmd, "(pager-move-window %ld %d %d %d %d %d %d)",
	     dragged_window->id, x-offset_x, y-offset_y,
	     dragged_window->w.width, dragged_window->w.height,
	     x, y );
    send_command( cmd );
    dragged_window = NULL;
  }
  return TRUE;
}


gint configure_event( GtkWidget *widget, GdkEvent *event, gpointer data )
{
  int i;

  if( pixmap ) {
    gdk_pixmap_unref( pixmap );
    for( i = bg; i <= vp_frame; i++ )
      gdk_gc_unref( gc[i] );
  }

  pixmap = gdk_pixmap_new( widget->window, width, height, -1 );
  for( i = bg; i <= ws_divider; i++ )
    gdk_gc_set_foreground( gc[i] = gdk_gc_new( pixmap ), &colors[i] );

  /* wishing for a nicer line style, like 3 on, 5 off, making this alternate for neighbouring VPs */
  gdk_gc_set_line_attributes( gc[vp_divider], 1, GDK_LINE_ON_OFF_DASH,
			      GDK_CAP_ROUND, GDK_JOIN_ROUND );
  gdk_gc_set_foreground( gc[vp_frame] = gdk_gc_new( pixmap ), &colors[vp_divider] );
  gdk_gc_set_line_attributes( gc[vp_frame], 1, GDK_LINE_ON_OFF_DASH,
			      GDK_CAP_ROUND, GDK_JOIN_ROUND );
  /* wishing for Gimp-style functions -- GDK is just too primitive */
  /* gdk_gc_set_function( gc[vp_frame], GDK_XOR ); */

  make_background();
  draw_pager( widget );

  return TRUE;
}


void make_background()
{
  if( background )
    gdk_pixmap_unref( background );
  if( ! (*bg_filename &&
	 (background = gdk_pixmap_create_from_xpm( window->window, NULL, NULL, bg_filename ))) )
  {
    int i, j;
    background = gdk_pixmap_new( window->window, ws_width, ws_height, -1 );
    gdk_draw_rectangle( background, gc[bg], TRUE, 1, 1, ws_width, ws_height );

    /* draw the boundaries of the different viewports */
    if( vp_width < ws_width-1 || vp_height < ws_height-1 )
      for( i=1; i<ws_width; i+=vp_width )
	for( j=1; j<ws_height; j+=vp_height )
	  gdk_draw_rectangle( background, gc[vp_divider], FALSE,
			      i+1, j+1, vp_width-3, vp_height-3 );

    /* draw the workspace-boundary (repeated by tiling) */
    gdk_draw_line( background, gc[ws_divider], 0, 0, 0, ws_height );
    gdk_draw_line( background, gc[ws_divider], 1, 0, ws_width, 0 );
  }
  gdk_gc_set_fill( gc[bg], GDK_TILED );
  gdk_gc_set_tile( gc[bg], background );
}


void draw_pager( GtkWidget *widget )
{
  if( show_all_ws )
    box( bg, TRUE, 0, 0, width, height );
  else
    box( bg, TRUE, -ws_x, -ws_y, width+ws_x, height+ws_y );

  /* highlight the current viewport with color hilit background */
  if(xmark ==0)
    box( hilit_bg, TRUE, vp_x, vp_y, vp_width, vp_height );

  /* draw the windows */
  if(hatch == 0)
  {
    for( w = lowest; w >= windows; w-- ) {
      clipbox( (w->id == focus_id) ? focus_win : win, TRUE,
               w->w.x+1, w->w.y+1, w->w.width-2, w->w.height-2, &w->c );
      clipbox( win_border, FALSE,
               w->w.x, w->w.y, w->w.width-1, w->w.height-1, &w->c );
    }
  } else {
    for( w = lowest; w >= windows; w-- ) {
      int i;
      if(w->id == focus_id)
      {
        for(i=((w->w.width > w->w.height)?w->w.width:w->w.height)>>1; i>=1 ; i-=2)
          clipbox(focus_win, FALSE, w->w.x+i, w->w.y+1, w->w.width-1-(i<<1), w->w.height-1, &w->c );
      } else {
        for(i=((w->w.width > w->w.height)?w->w.width:w->w.height)>>1; i>=1 ; i-=2)
          clipbox(win,       FALSE, w->w.x+1, w->w.y+i, w->w.width-1, w->w.height-1-(i<<1), &w->c );
      }
/*      for(i=((w->w.width > w->w.height)?w->w.width:w->w.height)>>1; i>=1 ; i-=2)
        clipbox( (w->id == focus_id) ? focus_win : win, FALSE, w->w.x+i, w->w.y+i, w->w.width-1-(i<<1), w->w.height-1-(i<<1), &w->c );
        clipbox( (w->id == focus_id) ? focus_win : win, FALSE, w->w.x+1, w->w.y+1, w->w.width-3, w->w.height-3, &w->c );
        clipbox( (w->id == focus_id) ? focus_win : win, FALSE, w->w.x+2, w->w.y+2, w->w.width-5, w->w.height-5, &w->c );
        clipbox( (w->id == focus_id) ? focus_win : win, FALSE, w->w.x+3, w->w.y+3, w->w.width-7, w->w.height-7, &w->c ); */
        clipbox( win_border,                            FALSE, w->w.x, w->w.y, w->w.width-1, w->w.height-1, &w->c );
    }
  }

  /* frame the current viewport above all else in case it's covered */
  if( vp_width < ws_width-1 || vp_height < ws_height-1 )
  {
    if(xmark == 0)
    {
      box( vp_frame, FALSE, vp_x, vp_y, vp_width-1, vp_height-1 );
    } else
    {
      /* box( vp_frame, FALSE, vp_x+1, vp_y+1, vp_width-3, vp_height-3 ); */
      box( hilit_bg, FALSE, vp_x, vp_y, vp_width-1, vp_height-1 );
      gdk_draw_line(pixmap,gc[hilit_bg],vp_x    ,               vp_y + 2 , vp_width-1 + vp_x - 2, vp_height-1 + vp_y    );
      gdk_draw_line(pixmap,gc[hilit_bg],vp_x    , vp_height-1 + vp_y - 2 , vp_width-1 + vp_x - 2,               vp_y    );

      gdk_draw_line(pixmap,gc[hilit_bg],vp_x + 2,               vp_y     , vp_width-1 + vp_x    , vp_height-1 + vp_y - 2);
      gdk_draw_line(pixmap,gc[hilit_bg],vp_x + 2, vp_height-1 + vp_y     , vp_width-1 + vp_x    ,               vp_y + 2);
    }
  }

  gtk_widget_draw( widget, &update_rect );
}

gint draw_tooltip()
{
  if( find_w( mouse_x, mouse_y )) {
    if( w != tooltip_window ) {
      char cmd[64];
      tooltip_window = w;
      sprintf( cmd, "(pager-tooltip %ld)", w->id );
      send_command( cmd );
    }
    return TRUE;
  } else if( tooltip_window )
    send_command( "(pager-tooltip)" );
  tooltip_window = NULL;
  return FALSE;
}



char get_char( int must )
{
  static char buffer[MAXSTRING];
  static char *ptr = buffer;
  static int n = 0;

  if( ++ptr < buffer + n )
    return *ptr;
  else if( must ) {
    n = read( 0, buffer, MAXSTRING );
    if( n < 1 )
      exit( 1 );
    return *(ptr = buffer);
  } else {
    /* input waiting? */
    fd_set rfds;
    struct timeval tv;
    FD_ZERO( &rfds );
    FD_SET( 0, &rfds );
    tv.tv_sec = tv.tv_usec = 0;
    if( select( 1, &rfds, NULL, NULL, &tv ) ) {
      n = read( 0, buffer, MAXSTRING );
      if( n < 1 )
	exit( 1 );
      return *(ptr = buffer);
    } else
      return '\0';
  }
}

int last;
long get_number()
{
  char buffer;
  long number = 0;
  int sign = 1;
  while( (buffer = get_char( 1 )) ) {
    if( buffer >= '0' && buffer <= '9' )
      number = number * 10 + buffer - '0';
    else if( (last = (buffer == '\n')) || buffer == ' ' ) {
      if( sign == -1 )
	number = -number;
      break;
    } else if( buffer == '-' )
      sign = -1;
  }
  return number;
}

void get_string( char *buffer )
{
  char *ptr = buffer;
  while( (*ptr = get_char( 1 )) )
    if( *ptr == '\n' )
      break;
    else if( ptr < buffer + MAXSTRING - 1 )
      ptr++;
  *ptr = '\0';
}

void get_rect( GdkRectangle *r )
{
  r->x = get_number();
  r->y = get_number();
  r->width = get_number();
  r->height = get_number();
}

/* This reads and returns the type of the data:
 *	W - regular info about what to display
 *	s - size info to resize the window
 *	b - background image file
 *	c - color change
 *	w - info about one window
 *	f - focus change
 *      H - hatching
 *      X - draw X-es
 */
void parse_stdin()
{
  long i;
  int repeat, more = 0;

  while( 1 )
    switch( get_char( ! more++ ) ) {
    case 'f':
      focus_id = get_number();
      break;
    case 'v':
      ws_x = get_number();
      ws_y = get_number();
      vp_x = ws_x + get_number();
      vp_y = ws_y + get_number();
      break;
    case 'W':
      last = 0;
      lowest = windows - 1;
      while( !last ) {
	if( lowest >= windows + MAXWINDOWS )
	  get_number();		/* flush input in excess of MAXWINDOWS */
	else if( ((lowest+1)->id = get_number()) ) {
	  get_rect( &(++lowest)->w );
	  get_rect( &lowest->c );
	}
      }
      break;
    case 'w':
      /* should never get here for an unknown window */
      i = get_number();
      for( w = lowest; w >= windows; w-- ) {
	if( w->id == i ) {
	  get_rect( &w->w );
	  get_rect( &w->c );
	  break;
	}
      }
      break;
    case 'h':
      hatch = get_number(); // this number is a 0 or 1
      break;
    case 'x':
      xmark = get_number(); // this number is a 0 or 1
      break;
    case 's':
      show_all_ws = get_number();
      vp_width = get_number();
      vp_height = get_number();
      ws_width = get_number();
      ws_height = get_number();
      width = update_rect.width = get_number() + 1;
      height = update_rect.height = get_number() + 1;
      /* Initialize the picture */
      gdk_window_resize( window->window, width, height );
      gtk_drawing_area_size( GTK_DRAWING_AREA( drawing_area ), width, height );
      break;
    case 'b':
      get_string( bg_filename );
      if( pixmap )
	make_background();
      break;
    case 'c':
      repeat = (cmap != NULL);
      cmap = gdk_colormap_get_system();
      for( i = bg; i <= ws_divider; i++ ) {
	if( repeat )
	  gdk_colormap_free_colors( cmap, &colors[i], 1 );
	colors[i].red = get_number();
	colors[i].green = get_number();
	colors[i].blue = get_number();
	gdk_color_alloc( cmap, &colors[i] );
      }
      break;
    case '\0':
      return;
    }
}

void
wait_stdin( gpointer data, gint source, GdkInputCondition cond )
{
  parse_stdin();
  draw_pager( data );
  draw_tooltip();
}

gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data )
{
  return FALSE;
}

gint destroy_event( GtkWidget *widget, GdkEvent *event, gpointer data )
{
  gtk_main_quit();
  return FALSE;
}

/* This function is borrowed from galeon's source */
static void wmspec_change_state( gboolean add, GdkWindow *window,
				 GdkAtom state1, GdkAtom state2 )
{
  XEvent xev;
#define _NET_WM_STATE_REMOVE        0    /* remove/unset property */
#define _NET_WM_STATE_ADD           1    /* add/set property */
#define _NET_WM_STATE_TOGGLE        2    /* toggle property  */
  xev.xclient.type = ClientMessage;
  xev.xclient.serial = 0;
  xev.xclient.send_event = True;
  xev.xclient.display = gdk_display;
  xev.xclient.window = GDK_WINDOW_XID (window);
  xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_WM_STATE");
  xev.xclient.format = 32;
  xev.xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
  xev.xclient.data.l[1] = gdk_x11_atom_to_xatom (state1);
  xev.xclient.data.l[2] = gdk_x11_atom_to_xatom (state2);
  XSendEvent(gdk_display, GDK_WINDOW_XID (gdk_get_default_root_window ()),
		  False, SubstructureRedirectMask | SubstructureNotifyMask,
		  &xev);
}

Attachment: signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]