Strange behaviour on dual screen setup



Hi,

I'm experimenting a strange behaviour when I try to put a window on a
different screen than the one on which the application was run. I'm
doing this because I'm writing an application that should run
full-screen on a multi-monitor workstation.

The problem is that when I click on the window on the second screen, I
get a "dummy" mouse-leave event, and from that moment on the
mouse-movement events are not dispathed until I move the mouse out of
the window and into it again. This behaviour does not occour on the
other window (the one on the first screen).

Can someone shed some light on this? Am I using the set_screen in a wrong way?

BTW everything works if I switch to xinerama (using only one screen
with two monitors, instead of two screen, one per monitor) and use
window->move instead of window->set_screen, but I think this is
somewhat strange... Any help will be greatly appreciated.

In attachment I'm sending a small program that shows what my problem
is. It expects to run on a display with two screens (no xinerama).
Compile with

g++ `pkg-config --libs --cflags gtkmm-2.4 ` TestNoisy.cpp
NoisyWidget.cpp -o noisy

Thanks

Oscar Lazzarino.
#include "NoisyWidget.h"

#include <iostream>
#include <cmath>
#include <cstdio>
#include <gdk/gdkx.h>

bool NoisyWidget::fillEventMotion(GdkEventMotion* pEventMotion)
{
    if (pEventMotion->is_hint)
    {
        int lX, lY;
        Gdk::ModifierType lState;
        get_window()->get_pointer(lX, lY, lState);
//         pEventMotion->x = lX;
//         pEventMotion->y = mWidget->get_height() - lY - 1;
        pEventMotion->state = lState;

        return true;
    }//if

    return false;
}

NoisyWidget::NoisyWidget()
{
		add_events(Gdk::POINTER_MOTION_MASK |
				Gdk::BUTTON_MOTION_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK |
				Gdk::BUTTON3_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK |
				Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK | Gdk::ENTER_NOTIFY_MASK |
				Gdk::LEAVE_NOTIFY_MASK);
		set_flags(get_flags() | Gtk::CAN_FOCUS);

}

void NoisyWidget::on_realize()
{
	std::cout << "on_realize()\n";
	Gtk::DrawingArea::on_realize();
//		add_events(Gdk::ALL_EVENTS_MASK);
}

bool NoisyWidget::on_expose_event(GdkEventExpose* event)
{
	std::cout << "on_expose_event()\n";
	return Gtk::DrawingArea::on_expose_event(event);
}

void NoisyWidget::on_map () 
{
	std::cout << "on_map()\n";
	Gtk::DrawingArea::on_map();
}

bool NoisyWidget::on_map_event (GdkEventAny* event)
{
	std::cout << "on_map_event()\n";
	return Gtk::DrawingArea::on_map_event(event);
}

void NoisyWidget::on_unmap ()
{
	std::cout << "on_unmap()\n";
	Gtk::DrawingArea::on_unmap();
}

bool NoisyWidget::on_unmap_event (GdkEventAny* event)
{
	std::cout << "on_unmap_event()\n";
	return Gtk::DrawingArea::on_unmap_event(event);
}

void NoisyWidget::on_unrealize ()
{
	std::cout << "on_unrealize()\n";
	Gtk::DrawingArea::on_unrealize();
}

void NoisyWidget::on_show()
{
	std::cout << "on_show()\n";
	Gtk::DrawingArea::on_show();
}

void NoisyWidget::on_hide()
{
	std::cout << "on_hide()\n";
	Gtk::DrawingArea::on_hide();
}
	
bool NoisyWidget::on_configure_event (GdkEventConfigure* event)
{
	std::cout << "on_configure_event()\n";
	std::cout << "   x, y = " << event->x << ", " << event->y << std::endl;
	std::cout << "   w, h = " << event->width << ", " << event->height << std::endl;
	return Gtk::DrawingArea::on_configure_event(event);
}

void NoisyWidget::on_size_allocate(Gtk::Allocation& allocation)
{
	std::cout << "on_configure_event()\n";
	std::cout << "   x, y = " << allocation.get_x() << ", " << allocation.get_y() << std::endl;
	std::cout << "   w, h = " << allocation.get_width() << ", " << allocation.get_height() << std::endl;
	Gtk::DrawingArea::on_size_allocate(allocation);
}

bool NoisyWidget::on_delete_event (GdkEventAny* event)
{
	std::cout << "on_delete_event()\n";
	return Gtk::DrawingArea::on_delete_event(event);
}

bool NoisyWidget::on_button_press_event (GdkEventButton* event) 
{
	std::cout << "on_button_press_event()\n";
//	hide();
	return Gtk::DrawingArea::on_button_press_event(event);
}

bool NoisyWidget::on_button_release_event (GdkEventButton* event) 
{
	std::cout << "on_button_release_event()\n";
	return Gtk::DrawingArea::on_button_release_event(event);
}

bool NoisyWidget::on_motion_notify_event (GdkEventMotion *event)
{
	std::cout << "on_motion_notify_event()\n";
	std::cout << "   x, y = " << event->x << ", " << event->y << std::endl;
	//fillEventMotion(event);
	return Gtk::DrawingArea::on_motion_notify_event(event);
}

bool NoisyWidget::on_enter_notify_event(GdkEventCrossing* pEvent)
{
	std::cout << "on_enter_notify_event()\n";
	std::cout << "   state = " << pEvent->state << std::endl;
	return Gtk::DrawingArea::on_enter_notify_event(pEvent);
}

bool NoisyWidget::on_leave_notify_event(GdkEventCrossing* pEvent)
{
	std::cout << "on_leave_notify_event()\n";
	std::cout << "   state = " << pEvent->state << std::endl;
	return Gtk::DrawingArea::on_leave_notify_event(pEvent);
}

bool NoisyWidget::on_key_press_event(GdkEventKey* pEvent)
{
	std::cout << "on_key_press_event()\n";
	return Gtk::DrawingArea::on_key_press_event(pEvent);
}

bool NoisyWidget::on_key_release_event(GdkEventKey* pEvent)
{
	std::cout << "on_key_release_event()\n";
	return Gtk::DrawingArea::on_key_release_event(pEvent);
}
#ifndef TOTAL_SCORE_H
#define TOTAL_SCORE_H

#include <gtkmm.h>
#include <gdkmm.h>
#include <vector>
#include <boost/shared_ptr.hpp>

class NoisyWidget : public Gtk::DrawingArea
{
	public:
		NoisyWidget();

	protected:
		virtual void on_realize();
		virtual void on_unrealize ();

		virtual bool on_expose_event(GdkEventExpose* event);
		virtual void on_size_allocate(Gtk::Allocation& allocation);

		virtual void on_map ();
		virtual bool on_map_event (GdkEventAny* event);
		virtual void on_unmap ();
		virtual bool on_unmap_event (GdkEventAny* event);

		virtual void on_show ();
		virtual void on_hide ();

		virtual bool on_configure_event (GdkEventConfigure* event);
		virtual bool on_delete_event (GdkEventAny* event);

		virtual bool on_button_press_event (GdkEventButton* event);
		virtual bool on_button_release_event (GdkEventButton* event);

		virtual bool on_motion_notify_event (GdkEventMotion *event);

		bool on_enter_notify_event(GdkEventCrossing* pEvent);
		bool on_leave_notify_event(GdkEventCrossing* pEvent);

		bool on_key_press_event(GdkEventKey* pEvent);
		bool on_key_release_event(GdkEventKey* pEvent);


		bool fillEventMotion(GdkEventMotion* pEventMotion);
};

#endif // TOTAL_SCORE_H

#include "NoisyWidget.h"
#include <gtkmm.h>
#include <glibmm.h>
#include <iostream>

#include "MessageButton.h"
#include "LaunchButton.h"

NoisyWidget *mNoisy1, *mNoisy2;

int main(int argc, char** argv)
{
	Gtk::Main kit(argc, argv);

	mNoisy1 = new NoisyWidget();	
	mNoisy1->add_events(Gdk::ALL_EVENTS_MASK);
	mNoisy1->show();

	Gtk::Window win1;
	win1.add_events(Gdk::ALL_EVENTS_MASK);
	win1.set_title("Noisy1");
	win1.set_size_request(300, 300);
	win1.add(*mNoisy1);
	win1.show();

	Glib::RefPtr<Gdk::Display> lDisplay = win1.get_display();
	Glib::RefPtr<Gdk::Screen> lScreen = lDisplay->get_screen(1);

	mNoisy2 = new NoisyWidget();
	mNoisy1->add_events(Gdk::ALL_EVENTS_MASK);
	mNoisy2->show();

	Gtk::Window win2;
	win1.add_events(Gdk::ALL_EVENTS_MASK);
	win2.set_title("Noisy2");
	win2.set_size_request(300, 300);
	win2.set_screen(lScreen);
	win2.add(*mNoisy2);
	win2.show();
 
	Gtk::Main::run();
 
	return 0;
}


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