Пример #1
0
static bool wxQueryWMspecSupport(Display* WXUNUSED(display),
                                 Window WXUNUSED(rootWnd),
                                 Atom (feature))
{
    GdkAtom gatom = gdk_x11_xatom_to_atom(feature);
    return gdk_x11_screen_supports_net_wm_hint(gdk_screen_get_default(), gatom);
}
Пример #2
0
static guint32
get_netwm_cardinal_property (GdkScreen   *screen,
                             const gchar *name)
{
  GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
  GdkAtom atom;
  guint32 prop = 0;
  Atom type;
  gint format;
  gulong nitems;
  gulong bytes_after;
  guchar *data;

  atom = gdk_atom_intern_static_string (name);

  if (!gdk_x11_screen_supports_net_wm_hint (screen, atom))
    return 0;

  XGetWindowProperty (x11_screen->xdisplay,
                      x11_screen->xroot_window,
                      gdk_x11_get_xatom_by_name_for_display (GDK_SCREEN_DISPLAY (screen), name),
                      0, G_MAXLONG,
                      False, XA_CARDINAL, &type, &format, &nitems,
                      &bytes_after, &data);
  if (type == XA_CARDINAL)
    {
      prop = *(gulong *)data;
      XFree (data);
    }

  return prop;
}
Пример #3
0
/* Handler for "clicked" signal on main widget. */
static gboolean wincmd_button_clicked(GtkWidget * widget, GdkEventButton * event, LXPanel * panel)
{
    WinCmdPlugin * wc = lxpanel_plugin_get_data(widget);

    /* Left-click to iconify. */
    if (event->button == 1)
    {
        GdkScreen* screen = gtk_widget_get_screen(widget);
        static GdkAtom atom = 0;
        if( G_UNLIKELY(0 == atom) )
            atom = gdk_atom_intern("_NET_SHOWING_DESKTOP", FALSE);

        /* If window manager supports _NET_SHOWING_DESKTOP, use it.
         * Otherwise, fall back to iconifying windows individually. */
        if (gdk_x11_screen_supports_net_wm_hint(screen, atom))
        {
            int showing_desktop = ((( ! wc->toggle_preference) || ( ! wc->toggle_state)) ? 1 : 0);
            Xclimsg(DefaultRootWindow(GDK_DISPLAY_XDISPLAY(gdk_display_get_default())),
                    a_NET_SHOWING_DESKTOP, showing_desktop, 0, 0, 0, 0);
            wincmd_adjust_toggle_state(wc);
        }
        else
            wincmd_execute(wc, WC_ICONIFY);
    }

    /* Middle-click to shade. */
    else if (event->button == 2)
        wincmd_execute(wc, WC_SHADE);

    return TRUE;
}
Пример #4
0
static void button_toggled_callback(GtkWidget* button, ShowDesktopData* sdd)
{
	if (!gdk_x11_screen_supports_net_wm_hint(gtk_widget_get_screen(button), gdk_atom_intern("_NET_SHOWING_DESKTOP", FALSE)))
	{
		static GtkWidget* dialog = NULL;

		if (dialog && gtk_widget_get_screen(dialog) != gtk_widget_get_screen(button))
			gtk_widget_destroy (dialog);

		if (dialog)
		{
			gtk_window_present(GTK_WINDOW(dialog));
			return;
		}

		dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Your window manager does not support the show desktop button, or you are not running a window manager."));

		g_object_add_weak_pointer(G_OBJECT(dialog), (gpointer) &dialog);

		g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), NULL);

		gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
		gtk_window_set_screen(GTK_WINDOW(dialog), gtk_widget_get_screen(button));
		gtk_widget_show(dialog);

		return;
	}

	if (sdd->matewnck_screen != NULL)
		matewnck_screen_toggle_showing_desktop(sdd->matewnck_screen, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)));

	update_button_display (sdd);
}
Пример #5
0
static GList *
gdk_x11_screen_get_window_stack (GdkScreen *screen)
{
  GdkX11Screen *x11_screen;
  GList *ret = NULL;
  Atom type_return;
  gint format_return;
  gulong nitems_return;
  gulong bytes_after_return;
  guchar *data = NULL;

  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);

  if (!gdk_x11_screen_supports_net_wm_hint (screen,
                                            gdk_atom_intern_static_string ("_NET_CLIENT_LIST_STACKING")))
    return NULL;

  x11_screen = GDK_X11_SCREEN (screen);

  if (XGetWindowProperty (x11_screen->xdisplay, x11_screen->xroot_window,
	                  gdk_x11_get_xatom_by_name_for_display (x11_screen->display,
			                                         "_NET_CLIENT_LIST_STACKING"),
		          0, G_MAXLONG, False, XA_WINDOW, &type_return,
		          &format_return, &nitems_return,
                          &bytes_after_return, &data)
      == Success)
    {
      if ((type_return == XA_WINDOW) && (format_return == 32) &&
          (data) && (nitems_return > 0))
        {
          gulong *stack = (gulong *) data;
          GdkWindow *win;
          int i;

          for (i = 0; i < nitems_return; i++)
            {
              win = gdk_x11_window_foreign_new_for_display (x11_screen->display,
                                                            (Window)stack[i]);

              if (win != NULL)
                ret = g_list_append (ret, win);
            }
        }
    }

  if (data)
    XFree (data);

  return ret;
}
Пример #6
0
/* This function will make sure that tilda window becomes active (gains
 * the focus) when it is called.
 *
 * This has to be the worst possible way of making this work, but it was the
 * only way to get metacity to play nicely. All the other WM's are so nice,
 * why oh why does metacity hate us so?
 */
void tilda_window_set_active (tilda_window *tw)
{
    DEBUG_FUNCTION ("tilda_window_set_active");
    DEBUG_ASSERT (tw != NULL);

    Display *x11_display = GDK_WINDOW_XDISPLAY (gtk_widget_get_window (tw->window) );
    Window x11_window = GDK_WINDOW_XID (gtk_widget_get_window (tw->window) );
    Window x11_root_window = GDK_WINDOW_XID ( gtk_widget_get_root_window (tw->window) );
    GdkScreen *screen = gtk_widget_get_screen (tw->window);

    XEvent event;
    long mask = SubstructureRedirectMask | SubstructureNotifyMask;
    gtk_window_move (GTK_WINDOW(tw->window), config_getint ("x_pos"), config_getint ("y_pos"));
    if (gdk_x11_screen_supports_net_wm_hint (screen,
                                             gdk_atom_intern_static_string ("_NET_ACTIVE_WINDOW")))
    {
        guint32 timestamp = gtk_get_current_event_time ();
        if (timestamp == 0) {
            timestamp = gdk_x11_get_server_time(gdk_screen_get_root_window (screen));
        }
        event.xclient.type = ClientMessage;
        event.xclient.serial = 0;
        event.xclient.send_event = True;
        event.xclient.display = x11_display;
        event.xclient.window = x11_window;
        event.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW");

        event.xclient.format = 32;
        event.xclient.data.l[0] = 2; /* pager */
        event.xclient.data.l[1] = timestamp; /* timestamp */
        event.xclient.data.l[2] = 0;
        event.xclient.data.l[3] = 0;
        event.xclient.data.l[4] = 0;

        XSendEvent (x11_display, x11_root_window, False, mask, &event);
    }
    else
    {
        /* The WM doesn't support the EWMH standards. We'll print a warning and
         * try this, though it probably won't work... */
        g_printerr (_("WARNING: Window manager (%s) does not support EWMH hints\n"),
                    gdk_x11_screen_get_window_manager_name (screen));
        XRaiseWindow (x11_display, x11_window);
    }
}
Пример #7
0
static GdkWindow *
gdk_x11_screen_get_active_window (GdkScreen *screen)
{
  GdkX11Screen *x11_screen;
  GdkWindow *ret = NULL;
  Atom type_return;
  gint format_return;
  gulong nitems_return;
  gulong bytes_after_return;
  guchar *data = NULL;

  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);

  if (!gdk_x11_screen_supports_net_wm_hint (screen,
                                            gdk_atom_intern_static_string ("_NET_ACTIVE_WINDOW")))
    return NULL;

  x11_screen = GDK_X11_SCREEN (screen);

  if (XGetWindowProperty (x11_screen->xdisplay, x11_screen->xroot_window,
	                  gdk_x11_get_xatom_by_name_for_display (x11_screen->display,
			                                         "_NET_ACTIVE_WINDOW"),
		          0, 1, False, XA_WINDOW, &type_return,
		          &format_return, &nitems_return,
                          &bytes_after_return, &data)
      == Success)
    {
      if ((type_return == XA_WINDOW) && (format_return == 32) && (data))
        {
          Window window = *(Window *) data;

          if (window != None)
            {
              ret = gdk_x11_window_foreign_new_for_display (x11_screen->display,
                                                            window);
            }
        }
    }

  if (data)
    XFree (data);

  return ret;
}
void
gdk_x11_window_force_focus (GdkWindow *window,
                            guint32    timestamp)
{
    GdkDisplay *display;

    g_return_if_fail (GDK_IS_WINDOW (window));

    display = GDK_WINDOW_DISPLAY (window);

    if (GTK_CHECK_VERSION(3,0,0) && !GDK_IS_X11_DISPLAY (display))
        return;

    if (gdk_x11_screen_supports_net_wm_hint (gdk_window_get_screen (window),
                        gdk_atom_intern_static_string ("_NET_ACTIVE_WINDOW")))
    {
        if (!timestamp)
        {
            GTimeVal t;
            g_get_current_time (&t);
            timestamp = t.tv_sec;
        }

        XClientMessageEvent xclient;

        memset (&xclient, 0, sizeof (xclient));
        xclient.type = ClientMessage;
        xclient.window = GDK_WINDOW_XID (window);
        xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display,
                                                                    "_NET_ACTIVE_WINDOW");
        xclient.format = 32;
        xclient.data.l[0] = 2; /* requestor type; we're a tool */
        xclient.data.l[1] = timestamp;
        xclient.data.l[2] = None; /* currently active window */
        xclient.data.l[3] = 0;
        xclient.data.l[4] = 0;

        XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
                    SubstructureRedirectMask | SubstructureNotifyMask,
                    (XEvent *)&xclient);
    }
}
Пример #9
0
static int
get_current_desktop (GdkScreen *screen)
{
  Display *display;
  Window win;
  Atom current_desktop, type;
  int format;
  unsigned long n_items, bytes_after;
  unsigned char *data_return = NULL;
  int workspace = 0;

  if (!gdk_x11_screen_supports_net_wm_hint (screen,
                                            gdk_atom_intern_static_string ("_NET_CURRENT_DESKTOP")))
    return workspace;

  display = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (screen));
  win = XRootWindow (display, GDK_SCREEN_XNUMBER (screen));

  current_desktop = XInternAtom (display, "_NET_CURRENT_DESKTOP", True);

  XGetWindowProperty (display,
                      win,
                      current_desktop,
                      0, G_MAXLONG,
                      False, XA_CARDINAL,
                      &type, &format, &n_items, &bytes_after,
                      &data_return);

  if (type == XA_CARDINAL && format == 32 && n_items > 0)
    workspace = ((long *) data_return)[0];

  if (data_return)
    XFree (data_return);

  return workspace;
}
Пример #10
0
bool wxTopLevelWindowGTK::Show( bool show )
{
    wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );

#ifdef GDK_WINDOWING_X11
    bool deferShow = show && !m_isShown && m_deferShow;
    if (deferShow)
    {
        deferShow = m_deferShowAllowed && gs_requestFrameExtentsStatus != 2 &&
            !gtk_widget_get_realized(m_widget) &&
            g_signal_handler_find(m_widget,
                GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA),
                g_signal_lookup("property_notify_event", GTK_TYPE_WIDGET),
                0, NULL, NULL, this);
        if (deferShow)
        {
            GdkScreen* screen = gtk_widget_get_screen(m_widget);
            GdkAtom atom = gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false);
            deferShow = gdk_x11_screen_supports_net_wm_hint(screen, atom) != 0;

            // If _NET_REQUEST_FRAME_EXTENTS not supported, don't allow changes
            // to m_decorSize, it breaks saving/restoring window size with
            // GetSize()/SetSize() because it makes window bigger between each
            // restore and save.
            m_updateDecorSize = deferShow;
        }

        m_deferShow = deferShow;
    }
    if (deferShow)
    {
        // Initial show. If WM supports _NET_REQUEST_FRAME_EXTENTS, defer
        // calling gtk_widget_show() until _NET_FRAME_EXTENTS property
        // notification is received, so correct frame extents are known.
        // This allows resizing m_widget to keep the overall size in sync with
        // what wxWidgets expects it to be without an obvious change in the
        // window size immediately after it becomes visible.

        // Realize m_widget, so m_widget->window can be used. Realizing normally
        // causes the widget tree to be size_allocated, which generates size
        // events in the wrong order. However, the size_allocates will not be
        // done if the allocation is not the default (1,1).
        GtkAllocation alloc;
        gtk_widget_get_allocation(m_widget, &alloc);
        const int alloc_width = alloc.width;
        if (alloc_width == 1)
        {
            alloc.width = 2;
            gtk_widget_set_allocation(m_widget, &alloc);
        }
        gtk_widget_realize(m_widget);
        if (alloc_width == 1)
        {
            alloc.width = 1;
            gtk_widget_set_allocation(m_widget, &alloc);
        }

        // send _NET_REQUEST_FRAME_EXTENTS
        XClientMessageEvent xevent;
        memset(&xevent, 0, sizeof(xevent));
        xevent.type = ClientMessage;
        GdkWindow* window = gtk_widget_get_window(m_widget);
        xevent.window = GDK_WINDOW_XID(window);
        xevent.message_type = gdk_x11_atom_to_xatom_for_display(
            gdk_window_get_display(window),
            gdk_atom_intern("_NET_REQUEST_FRAME_EXTENTS", false));
        xevent.format = 32;
        Display* display = GDK_DISPLAY_XDISPLAY(gdk_window_get_display(window));
        XSendEvent(display, DefaultRootWindow(display), false,
            SubstructureNotifyMask | SubstructureRedirectMask,
            (XEvent*)&xevent);

        if (gs_requestFrameExtentsStatus == 0)
        {
            // if WM does not respond to request within 1 second,
            // we assume support for _NET_REQUEST_FRAME_EXTENTS is not working
            m_netFrameExtentsTimerId =
                g_timeout_add(1000, request_frame_extents_timeout, this);
        }

        // defer calling gtk_widget_show()
        m_isShown = true;
        return true;
    }
#endif // GDK_WINDOWING_X11

    if (show && !gtk_widget_get_realized(m_widget))
    {
        // size_allocate signals occur in reverse order (bottom to top).
        // Things work better if the initial wxSizeEvents are sent (from the
        // top down), before the initial size_allocate signals occur.
        wxSizeEvent event(GetSize(), GetId());
        event.SetEventObject(this);
        HandleWindowEvent(event);
    }

    bool change = base_type::Show(show);

    if (change && !show)
    {
        // make sure window has a non-default position, so when it is shown
        // again, it won't be repositioned by WM as if it were a new window
        // Note that this must be done _after_ the window is hidden.
        gtk_window_move((GtkWindow*)m_widget, m_x, m_y);
    }

    return change;
}
Пример #11
0
/* Code to find the active window in order to collect stats for social
 * application browsing.
 */
static void
get_active_application_properties(HippoIdleMonitor *monitor,
                                  char            **wm_class,
                                  char            **title)
{
    Display *xdisplay = GDK_DISPLAY_XDISPLAY(monitor->display);
    int n_screens = gdk_display_get_n_screens(monitor->display);
    Atom net_active_window_x = gdk_x11_get_xatom_by_name_for_display(monitor->display,
                                                                     "_NET_ACTIVE_WINDOW");
    GdkAtom net_active_window_gdk = gdk_atom_intern("_NET_ACTIVE_WINDOW", FALSE);
    Window active_window = None;
    int i;

    Atom type;
    int format;
    unsigned long n_items;
    unsigned long bytes_after;
    guchar *data;
        
    if (wm_class)
        *wm_class = NULL;
    if (title)
        *title = NULL;

    /* Find the currently focused window by looking at the _NET_ACTIVE_WINDOW property
     * on all the screens of the display.
     */
    for (i = 0; i < n_screens; i++) {
        GdkScreen *screen = gdk_display_get_screen(monitor->display, i);
        GdkWindow *root = gdk_screen_get_root_window(screen);

        if (!gdk_x11_screen_supports_net_wm_hint (screen, net_active_window_gdk))
            continue;

        XGetWindowProperty (xdisplay, GDK_DRAWABLE_XID(root),
                            net_active_window_x,
                            0, 1, False, XA_WINDOW,
                            &type, &format, &n_items, &bytes_after, &data);
        if (type == XA_WINDOW) {
            active_window = *(Window *)data;
            XFree(data);
            break;
        }
    }

    /* Now that we have the active window, figure out the application name and WM class
     */
    gdk_error_trap_push();
        
    if (active_window && wm_class) {
        if (XGetWindowProperty (xdisplay, active_window,
                                XA_WM_CLASS,
                                0, G_MAXLONG, False, XA_STRING,
                                &type, &format, &n_items, &bytes_after, &data) == Success &&
            type == XA_STRING)
        {
            if (format == 8) {
                char **list;
                int count;
                
                count = gdk_text_property_to_utf8_list_for_display(monitor->display, GDK_TARGET_STRING,
                                                                   8, data, n_items, &list);

                if (count > 1)
                    *wm_class = g_strdup(list[1]);

                if (list)
                    g_strfreev(list);
            }
            
            XFree(data);
        }
    }

    if (active_window && title) {
        Atom utf8_string = gdk_x11_get_xatom_by_name_for_display(monitor->display, "UTF8_STRING");
        
        if (XGetWindowProperty (xdisplay, active_window,
                                gdk_x11_get_xatom_by_name_for_display(monitor->display, "_NET_WM_NAME"),
                                0, G_MAXLONG, False, utf8_string,
                                &type, &format, &n_items, &bytes_after, &data) == Success &&
            type == utf8_string)
        {
            if (format == 8 && g_utf8_validate((char *)data, -1, NULL)) {
                *title = g_strdup((char *)data);
            }
            
            XFree(data);
        }
    }

    if (active_window && title && *title == NULL) {
        if (XGetWindowProperty (xdisplay, active_window,
                                XA_WM_NAME,
                                0, G_MAXLONG, False, AnyPropertyType,
                                &type, &format, &n_items, &bytes_after, &data) == Success &&
            type != None)
        {
            if (format == 8) {
                char **list;
                int count;
                
                count = gdk_text_property_to_utf8_list_for_display(monitor->display,
                                                                   gdk_x11_xatom_to_atom_for_display(monitor->display, type),
                                                                   8, data, n_items, &list);

                if (count > 0)
                    *title = g_strdup(list[0]);
                
                if (list)
                    g_strfreev(list);
            }
            
            XFree(data);
        }
    }
        
    gdk_error_trap_pop();
}
Пример #12
0
int wxSystemSettingsNative::GetMetric( wxSystemMetric index, wxWindow* win )
{
    guchar *data = NULL;
    Atom type;
    int format;
    gulong nitems;
    GdkWindow *window = NULL;
    if(win && GTK_WIDGET_REALIZED(win->GetHandle()))
        window = win->GetHandle()->window;

    switch (index)
    {
        case wxSYS_BORDER_X:
        case wxSYS_BORDER_Y:
        case wxSYS_EDGE_X:
        case wxSYS_EDGE_Y:
        case wxSYS_FRAMESIZE_X:
        case wxSYS_FRAMESIZE_Y:
            // If a window is specified/realized, and it is a toplevel window, we can query from wm.
            // The returned border thickness is outside the client area in that case.
            if (window)
            {
                wxTopLevelWindow *tlw = wxDynamicCast(win, wxTopLevelWindow);
                if (!tlw)
                    return -1; // not a tlw, not sure how to approach
                else
                {
                    // Check if wm supports frame extents - we can't know
                    // the border widths if it does not.
#if GTK_CHECK_VERSION(2,2,0)
                    if (!gtk_check_version(2,2,0))
                    {
                        if (!gdk_x11_screen_supports_net_wm_hint(
                                gdk_drawable_get_screen(window),
                                gdk_atom_intern("_NET_FRAME_EXTENTS", false) ) )
                            return -1;
                    }
                    else
#endif
                    {
                        if (!gdk_net_wm_supports(gdk_atom_intern("_NET_FRAME_EXTENTS", false)))
                            return -1;
                    }

                    // Get the frame extents from the windowmanager.
                    // In most cases the top extent is the titlebar, so we use the bottom extent
                    // for the heights.
                    if (wxXGetWindowProperty(window, type, format, nitems, data))
                    {
                        int border_return = -1;

                        if ((type == XA_CARDINAL) && (format == 32) && (nitems >= 4) && (data))
                        {
                            switch(index)
                            {
                                case wxSYS_BORDER_X:
                                case wxSYS_EDGE_X:
                                case wxSYS_FRAMESIZE_X:
                                    border_return = ((long*)data)[1]; // width of right extent
                                    break;
                                default:
                                    border_return = ((long*)data)[3]; // height of bottom extent
                                    break;
                            }
                        }

                        if (data)
                            XFree(data);

                        return border_return;
                    }
                }
            }

            return -1; // no window specified

        case wxSYS_CURSOR_X:
        case wxSYS_CURSOR_Y:
#ifdef __WXGTK24__
            if (!gtk_check_version(2,4,0))
            {
                if (window)
                    return gdk_display_get_default_cursor_size(gdk_drawable_get_display(window));
                else
                    return gdk_display_get_default_cursor_size(gdk_display_get_default());
            }
            else
#endif
                return 16;

        case wxSYS_DCLICK_X:
        case wxSYS_DCLICK_Y:
            gint dclick_distance;
#if GTK_CHECK_VERSION(2,2,0)
            if (window && !gtk_check_version(2,2,0))
                g_object_get(gtk_settings_get_for_screen(gdk_drawable_get_screen(window)),
                                "gtk-double-click-distance", &dclick_distance, NULL);
            else
#endif
                g_object_get(gtk_settings_get_default(),
                                "gtk-double-click-distance", &dclick_distance, NULL);

            return dclick_distance * 2;

        case wxSYS_DRAG_X:
        case wxSYS_DRAG_Y:
            gint drag_threshold;
#if GTK_CHECK_VERSION(2,2,0)
            if (window && !gtk_check_version(2,2,0))
            {
                g_object_get(
                        gtk_settings_get_for_screen(gdk_drawable_get_screen(window)),
                        "gtk-dnd-drag-threshold",
                        &drag_threshold, NULL);
            }
            else
#endif
            {
                g_object_get(gtk_settings_get_default(),
                             "gtk-dnd-drag-threshold", &drag_threshold, NULL);
            }

            // The correct thing here would be to double the value
            // since that is what the API wants. But the values
            // are much bigger under GNOME than under Windows and
            // just seem to much in many cases to be useful.
            // drag_threshold *= 2;

            return drag_threshold;

        // MBN: ditto for icons
        case wxSYS_ICON_X:     return 32;
        case wxSYS_ICON_Y:     return 32;

        case wxSYS_SCREEN_X:
#if GTK_CHECK_VERSION(2,2,0)
            if (window && !gtk_check_version(2,2,0))
                return gdk_screen_get_width(gdk_drawable_get_screen(window));
            else
#endif
                return gdk_screen_width();

        case wxSYS_SCREEN_Y:
#if GTK_CHECK_VERSION(2,2,0)
            if (window && !gtk_check_version(2,2,0))
                return gdk_screen_get_height(gdk_drawable_get_screen(window));
            else
#endif
                return gdk_screen_height();

        case wxSYS_HSCROLL_Y:  return 15;
        case wxSYS_VSCROLL_X:  return 15;

        case wxSYS_CAPTION_Y:
            if (!window)
                // No realized window specified, and no implementation for that case yet.
                return -1;

            // Check if wm supports frame extents - we can't know the caption height if it does not.
#if GTK_CHECK_VERSION(2,2,0)
            if (!gtk_check_version(2,2,0))
            {
                if (!gdk_x11_screen_supports_net_wm_hint(
                        gdk_drawable_get_screen(window),
                        gdk_atom_intern("_NET_FRAME_EXTENTS", false) ) )
                    return -1;
            }
            else
#endif
            {
                if (!gdk_net_wm_supports(gdk_atom_intern("_NET_FRAME_EXTENTS", false)))
                    return -1;
            }

            wxASSERT_MSG( wxDynamicCast(win, wxTopLevelWindow),
                          wxT("Asking for caption height of a non toplevel window") );

            // Get the height of the top windowmanager border.
            // This is the titlebar in most cases. The titlebar might be elsewhere, and
            // we could check which is the thickest wm border to decide on which side the
            // titlebar is, but this might lead to interesting behaviours in used code.
            // Reconsider when we have a way to report to the user on which side it is.
            if (wxXGetWindowProperty(window, type, format, nitems, data))
            {
                int caption_height = -1;

                if ((type == XA_CARDINAL) && (format == 32) && (nitems >= 3) && (data))
                {
                    caption_height = ((long*)data)[2]; // top frame extent
                }

                if (data)
                    XFree(data);

                return caption_height;
            }

            // Try a default approach without a window pointer, if possible
            // ...

            return -1;

        case wxSYS_PENWINDOWS_PRESENT:
            // No MS Windows for Pen computing extension available in X11 based gtk+.
            return 0;

        default:
            return -1;   // metric is unknown
    }
}
Пример #13
0
void
gdk_x11_screen_get_work_area (GdkScreen    *screen,
                              GdkRectangle *area)
{
  GdkX11Screen   *x11_screen = GDK_X11_SCREEN (screen);
  Atom            workarea;
  Atom            type;
  Window          win;
  int             format;
  gulong          num;
  gulong          leftovers;
  gulong          max_len = 4 * 32;
  guchar         *ret_workarea = NULL;
  long           *workareas;
  int             result;
  int             disp_screen;
  int             desktop;
  Display        *display;

  display = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (screen));
  disp_screen = GDK_SCREEN_XNUMBER (screen);
  workarea = XInternAtom (display, "_NET_WORKAREA", True);

  /* Defaults in case of error */
  area->x = 0;
  area->y = 0;
  area->width = gdk_screen_get_width (screen);
  area->height = gdk_screen_get_height (screen);

  if (!gdk_x11_screen_supports_net_wm_hint (screen,
                                            gdk_atom_intern_static_string ("_NET_WORKAREA")))
    return;

  if (workarea == None)
    return;

  win = XRootWindow (display, disp_screen);
  result = XGetWindowProperty (display,
                               win,
                               workarea,
                               0,
                               max_len,
                               False,
                               AnyPropertyType,
                               &type,
                               &format,
                               &num,
                               &leftovers,
                               &ret_workarea);
  if (result != Success ||
      type == None ||
      format == 0 ||
      leftovers ||
      num % 4 != 0)
    goto out;

  desktop = get_current_desktop (screen);
  if (desktop + 1 > num / 4) /* fvwm gets this wrong */
    goto out;

  workareas = (long *) ret_workarea;
  area->x = workareas[desktop * 4];
  area->y = workareas[desktop * 4 + 1];
  area->width = workareas[desktop * 4 + 2];
  area->height = workareas[desktop * 4 + 3];

  area->x /= x11_screen->window_scale;
  area->y /= x11_screen->window_scale;
  area->width /= x11_screen->window_scale;
  area->height /= x11_screen->window_scale;

out:
  if (ret_workarea)
    XFree (ret_workarea);
}
Пример #14
0
/* Code to find the active window in order to collect stats for social
 * application browsing.
 */
static void
get_active_application_properties(HippoIdleMonitor *monitor,
                                  char            **wm_class,
                                  char            **title)
{
    Display *xdisplay = GDK_DISPLAY_XDISPLAY(monitor->display);
    int n_screens = gdk_display_get_n_screens(monitor->display);
    Atom net_active_window_x = gdk_x11_get_xatom_by_name_for_display(monitor->display,
                                                                     "_NET_ACTIVE_WINDOW");
    GdkAtom net_active_window_gdk = gdk_atom_intern("_NET_ACTIVE_WINDOW", FALSE);
    Window active_window = None;
    int i;

    Atom type;
    int format;
    unsigned long n_items;
    unsigned long bytes_after;
    guchar *data;
    gboolean is_desktop = FALSE;
        
    if (wm_class)
        *wm_class = NULL;
    if (title)
        *title = NULL;

    /* Find the currently focused window by looking at the _NET_ACTIVE_WINDOW property
     * on all the screens of the display.
     */
    for (i = 0; i < n_screens; i++) {
        GdkScreen *screen = gdk_display_get_screen(monitor->display, i);
        GdkWindow *root = gdk_screen_get_root_window(screen);

        if (!gdk_x11_screen_supports_net_wm_hint (screen, net_active_window_gdk))
            continue;

        XGetWindowProperty (xdisplay, GDK_DRAWABLE_XID(root),
                            net_active_window_x,
                            0, 1, False, XA_WINDOW,
                            &type, &format, &n_items, &bytes_after, &data);
        if (type == XA_WINDOW) {
            active_window = *(Window *)data;
            XFree(data);
            break;
        }
    }

    /* Now that we have the active window, figure out the application name and WM class
     */
    gdk_error_trap_push();
        
    if (active_window && wm_class) {
        if (XGetWindowProperty (xdisplay, active_window,
                                XA_WM_CLASS,
                                0, G_MAXLONG, False, XA_STRING,
                                &type, &format, &n_items, &bytes_after, &data) == Success &&
            type == XA_STRING)
        {
            if (format == 8) {
                char **list;
                int count;
                
                count = gdk_text_property_to_utf8_list_for_display(monitor->display, GDK_TARGET_STRING,
                                                                   8, data, n_items, &list);

                if (count > 1) {
		    /* This is a check for Nautilus, which sets the instance to this
		     * value for the desktop window; we do this rather than check for
		     * the more general _NET_WM_WINDOW_TYPE_DESKTOP to avoid having
		     * to do another XGetProperty on every iteration. We generally
		     * don't want to count the desktop being focused as application
		     * usage because it frequently can be a false-positive of an
		     * empty workspace.
		     */
		    if (strcmp(list[0], "desktop_window") == 0)
			is_desktop = TRUE;
		    else
			*wm_class = g_strdup(list[1]);
		}

                if (list)
                    g_strfreev(list);
            }
            
            XFree(data);
        }
    }

    if (is_desktop)
	active_window = None;

    if (active_window && title) {
        Atom utf8_string = gdk_x11_get_xatom_by_name_for_display(monitor->display, "UTF8_STRING");
        
        if (XGetWindowProperty (xdisplay, active_window,
                                gdk_x11_get_xatom_by_name_for_display(monitor->display, "_NET_WM_NAME"),
                                0, G_MAXLONG, False, utf8_string,
                                &type, &format, &n_items, &bytes_after, &data) == Success &&
            type == utf8_string)
        {
            if (format == 8 && g_utf8_validate((char *)data, -1, NULL)) {
                *title = g_strdup((char *)data);
            }
            
            XFree(data);
        }
    }

    if (active_window && title && *title == NULL) {
        if (XGetWindowProperty (xdisplay, active_window,
                                XA_WM_NAME,
                                0, G_MAXLONG, False, AnyPropertyType,
                                &type, &format, &n_items, &bytes_after, &data) == Success &&
            type != None)
        {
            if (format == 8) {
                char **list;
                int count;
                
                count = gdk_text_property_to_utf8_list_for_display(monitor->display,
                                                                   gdk_x11_xatom_to_atom_for_display(monitor->display, type),
                                                                   8, data, n_items, &list);

                if (count > 0)
                    *title = g_strdup(list[0]);
                
                if (list)
                    g_strfreev(list);
            }
            
            XFree(data);
        }
    }
        
    gdk_error_trap_pop();
}