All pastes #1518821 Raw Edit

Someone

public diff v1 · immutable
#1518821 ·published 2009-08-05 05:59 UTC
rendered paste body
commit 27ad88d3c42d28c3da6fa03d35cf3d9532434cafAuthor: Chris Toshok <toshok@gmail.com>Date:   Tue Aug 4 19:33:58 2009 -0700    2009-08-04  Chris Toshok  <toshok@ximian.com>        	* popup.cpp (class GenerationClosure): new closure for emiting the    	Opened and Closed events.    	(Popup::emit_opened, Popup::emit_closed): pass the generation from    	the closure to ->Emit.    	(Popup::OnPropertyChanged): for the tick call, pass a closure that    	contains the current event generation.        	* timemanager.h, timemanager.cpp (TimeManager::InvokeTickCalls):    	factor out the loop for invoking tick calls here and call it from    	the source tick method.        	* window-gtk.cpp (MoonWindowGtk::button_press)    	(MoonWindowGtk::button_release, MoonWindowGtk::scroll)    	(MoonWindowGtk::motion_notify, MoonWindowGtk::crossing_notify)    	(MoonWindowGtk::focus_in, MoonWindowGtk::focus_out)    	(MoonWindowGtk::key_press, MoonWindowGtk::key_release): call    	TimeManager::InvokeTickCalls from each of these methods before we    	call the Surface::HandleUI* method.        	* dependencyobject.h (class EventObject): make a couple of api    	changes:    	(AddTickCall*): add an "EventObject* data" parameter.  if it's    	NULL, pass "this", so we have the current behavior.    	(DoEmit/Emit): add a "starting_generation" optional argument.  if    	it's supplied, we invoke only those handlers with tokens less than    	the starting_generation (i.e. those handlers that were registered    	before the event was generated.)diff --git a/src/ChangeLog b/src/ChangeLogindex 28a5010..2e3f59d 100644--- a/src/ChangeLog+++ b/src/ChangeLog@@ -1,3 +1,33 @@+2009-08-04  Chris Toshok  <toshok@ximian.com>++	* popup.cpp (class GenerationClosure): new closure for emiting the+	Opened and Closed events.+	(Popup::emit_opened, Popup::emit_closed): pass the generation from+	the closure to ->Emit.+	(Popup::OnPropertyChanged): for the tick call, pass a closure that+	contains the current event generation.++	* timemanager.h, timemanager.cpp (TimeManager::InvokeTickCalls):+	factor out the loop for invoking tick calls here and call it from+	the source tick method.++	* window-gtk.cpp (MoonWindowGtk::button_press)+	(MoonWindowGtk::button_release, MoonWindowGtk::scroll)+	(MoonWindowGtk::motion_notify, MoonWindowGtk::crossing_notify)+	(MoonWindowGtk::focus_in, MoonWindowGtk::focus_out)+	(MoonWindowGtk::key_press, MoonWindowGtk::key_release): call+	TimeManager::InvokeTickCalls from each of these methods before we+	call the Surface::HandleUI* method.++	* dependencyobject.h (class EventObject): make a couple of api+	changes:+	(AddTickCall*): add an "EventObject* data" parameter.  if it's+	NULL, pass "this", so we have the current behavior.+	(DoEmit/Emit): add a "starting_generation" optional argument.  if+	it's supplied, we invoke only those handlers with tokens less than+	the starting_generation (i.e. those handlers that were registered+	before the event was generated.)+ 2009-08-04  Larry Ewing  <lewing@novell.com>  	* uielement.cpp (DoMeasure): invalidate up the tree morediff --git a/src/dependencyobject.cpp b/src/dependencyobject.cppindex 5fa08bf..33b03ca 100644--- a/src/dependencyobject.cpp+++ b/src/dependencyobject.cpp@@ -201,7 +201,7 @@ EventObject::SetSurfaceUnlock () }  void-EventObject::AddTickCallSafe (TickCallHandler handler)+EventObject::AddTickCallSafe (TickCallHandler handler, EventObject *data) { 	int result; 	@@ -216,13 +216,13 @@ EventObject::AddTickCallSafe (TickCallHandler handler) 		return; 	} -	AddTickCallInternal (handler);+	AddTickCallInternal (handler, data);  	 	pthread_rwlock_unlock (&surface_lock); }  void-EventObject::AddTickCall (TickCallHandler handler)+EventObject::AddTickCall (TickCallHandler handler, EventObject *data) { 	if (!Surface::InMainThread ()) { 		g_warning ("EventObject::AddTickCall (): This method must not be called on any other than the main thread! Tick call won't be added.\n");@@ -233,11 +233,11 @@ EventObject::AddTickCall (TickCallHandler handler) 		return; 	} 	-	AddTickCallInternal (handler);+	AddTickCallInternal (handler, data); }  void-EventObject::AddTickCallInternal (TickCallHandler handler)+EventObject::AddTickCallInternal (TickCallHandler handler, EventObject *data) { 	Surface *surface; 	TimeManager *timemanager;@@ -259,7 +259,7 @@ EventObject::AddTickCallInternal (TickCallHandler handler) 		return; 	} -	timemanager->AddTickCall (handler, this);+	timemanager->AddTickCall (handler, data ? data : this); }  Deployment *@@ -723,8 +723,22 @@ EventObject::RemoveMatchingHandlers (int event_id, bool (*predicate)(EventHandle 	} } +int+EventObject::GetEventGeneration (int event_id)+{+	if (GetType()->GetEventCount() <= 0) {+		g_warning ("adding handler to event with id %d, which has not been registered\n", event_id);+		return -1;+	}+	+	if (events == NULL)+		events = new EventLists (GetType ()->GetEventCount ());+	+	return events->lists [event_id].current_token;+}+ bool-EventObject::Emit (char *event_name, EventArgs *calldata, bool only_unemitted)+EventObject::Emit (char *event_name, EventArgs *calldata, bool only_unemitted, int starting_generation) { 	Deployment *deployment = GetDeployment (); 	if (deployment && deployment->isDead)@@ -762,7 +776,7 @@ EventObject::EmitCallback (gpointer d) }  bool-EventObject::Emit (int event_id, EventArgs *calldata, bool only_unemitted)+EventObject::Emit (int event_id, EventArgs *calldata, bool only_unemitted, int starting_generation) { 	if (IsDisposed ()) 		return false;@@ -804,7 +818,7 @@ EventObject::Emit (int event_id, EventArgs *calldata, bool only_unemitted)  	EmitContext* ctx = StartEmit (event_id); -	DoEmit (event_id, ctx, calldata, only_unemitted);+	DoEmit (event_id, ctx, calldata, only_unemitted, starting_generation);  	if (calldata) 		calldata->unref ();@@ -861,7 +875,7 @@ EventObject::StartEmit (int event_id) }  bool-EventObject::DoEmit (int event_id, EmitContext *ctx, EventArgs *calldata, bool only_unemitted)+EventObject::DoEmit (int event_id, EmitContext *ctx, EventArgs *calldata, bool only_unemitted, int starting_generation) { 	EventClosure *xaml_closure = NULL; @@ -880,7 +894,8 @@ EventObject::DoEmit (int event_id, EmitContext *ctx, EventArgs *calldata, bool o #endif  		if (closure && closure->func-		    && (!only_unemitted || closure->emit_count == 0)) {+		    && (!only_unemitted || closure->emit_count == 0)+		    && (starting_generation == -1 || closure->token < starting_generation)) { 			closure->func (this, calldata, closure->data); 			closure->emit_count ++; 		}diff --git a/src/dependencyobject.h b/src/dependencyobject.hindex 6334eaf..20494e3 100644--- a/src/dependencyobject.h+++ b/src/dependencyobject.h@@ -154,8 +154,8 @@ public: 	//  Only AddTickCallSafe is safe to call on threads other than the main thread, 	//  and only if the type on which it is called overrides SetSurface and surrounds 	//  the call to the base type's SetSurface with SetSurfaceLock/Unlock.-	void AddTickCall (TickCallHandler handler);-	void AddTickCallSafe (TickCallHandler handler);+	void AddTickCall (TickCallHandler handler, EventObject *data = NULL);+	void AddTickCallSafe (TickCallHandler handler, EventObject *data = NULL);  	/* @GenerateCBinding,GeneratePInvoke */ 	void SetObjectType (Type::Kind value) { object_type = value; }@@ -168,7 +168,7 @@ public: 	void unref_delayed (); 	 	EmitContext *StartEmit (int event_id);-	bool DoEmit (int event_id, EmitContext *ctx, EventArgs *calldata = NULL, bool only_unemitted = false);+	bool DoEmit (int event_id, EmitContext *ctx, EventArgs *calldata = NULL, bool only_unemitted = false, int starting_generation = -1); 	void FinishEmit (int event_id, EmitContext *ctx); 	static gboolean EmitCallback (gpointer d); 	@@ -201,11 +201,13 @@ protected: 	 	// To enable scenarios like Emit ("Event", new EventArgs ()) 	// Emit will call unref on the calldata.-	bool Emit (char *event_name, EventArgs *calldata = NULL, bool only_unemitted = false);-	bool Emit (int event_id, EventArgs *calldata = NULL, bool only_unemitted = false);+	bool Emit (char *event_name, EventArgs *calldata = NULL, bool only_unemitted = false, int starting_generation = -1);+	bool Emit (int event_id, EventArgs *calldata = NULL, bool only_unemitted = false, int starting_generation = -1);++	int GetEventGeneration (int event_id);  private:-	void AddTickCallInternal (TickCallHandler handler);+	void AddTickCallInternal (TickCallHandler handler, EventObject *data = NULL); 	void Initialize (Deployment *deployment, Type::Kind type);  	EventLists *events;diff --git a/src/popup.cpp b/src/popup.cppindex 31678fa..c17af8f 100644--- a/src/popup.cpp+++ b/src/popup.cpp@@ -11,16 +11,48 @@ #include "popup.h" #include "runtime.h" +class GenerationClosure : public EventObject {+public:+	GenerationClosure (int generation, Popup *popup)+	{+		this->generation = generation;+		this->popup = popup;++		popup->ref ();+	}++	virtual ~GenerationClosure ()+	{+		popup->unref ();+	}++	int generation;+	Popup *popup;+};++ void Popup::emit_opened (EventObject *sender) {-	((Popup *)sender)->Emit (Popup::OpenedEvent);+	GenerationClosure *closure = (GenerationClosure *)sender;+	Popup * popup = closure->popup;+	int generation = closure->generation;++	closure->unref ();++	popup->Emit (Popup::OpenedEvent, NULL, false, generation); }  void Popup::emit_closed (EventObject *sender) {-	((Popup *)sender)->Emit (Popup::ClosedEvent);+	GenerationClosure *closure = (GenerationClosure *)sender;+	Popup * popup = closure->popup;+	int generation = closure->generation;++	closure->unref ();++	popup->Emit (Popup::ClosedEvent, NULL, false, generation); } 	 Popup::Popup ()@@ -62,11 +94,15 @@ Popup::OnPropertyChanged (PropertyChangedEventArgs *args, MoonError *error) 		// in SL. 		if (args->GetNewValue () && args->GetNewValue ()->AsBool ()) { 			Show (GetChild ());-			AddTickCall (Popup::emit_opened);+			AddTickCall (Popup::emit_opened,+				     new GenerationClosure (GetEventGeneration (Popup::OpenedEvent),+							    this)); 		} 		else { 			Hide (GetChild ());-			AddTickCall (Popup::emit_closed);+			AddTickCall (Popup::emit_closed,+				     new GenerationClosure (GetEventGeneration (Popup::ClosedEvent),+							    this)); 		} 	} else if (args->GetId () == Popup::ChildProperty) { 		if (args->GetOldValue () && !args->GetOldValue ()->GetIsNull ()) {diff --git a/src/timemanager.cpp b/src/timemanager.cppindex 15c4c58..4b37079 100644--- a/src/timemanager.cpp+++ b/src/timemanager.cpp@@ -181,6 +181,15 @@ TimeManager::InvokeTickCall () 	return true; } +void+TimeManager::InvokeTickCalls ()+{+	bool remaining_tick_calls = false;+	do {+		remaining_tick_calls = InvokeTickCall ();+	} while (remaining_tick_calls);+}+ guint TimeManager::AddTimeout (gint priority, guint ms_interval, GSourceFunc func, gpointer tick_data) {@@ -360,10 +369,7 @@ TimeManager::SourceTick () #endif  	if (current_flags & TIME_MANAGER_TICK_CALL) {-		bool remaining_tick_calls = false;-		do {-			remaining_tick_calls = InvokeTickCall ();-		} while (remaining_tick_calls);+		InvokeTickCalls (); 	}  	if (current_flags & TIME_MANAGER_UPDATE_CLOCKS) {diff --git a/src/timemanager.h b/src/timemanager.hindex 5f4e82c..5957c5d 100644--- a/src/timemanager.h+++ b/src/timemanager.h@@ -45,6 +45,8 @@ public: 	void NeedRedraw (); 	void NeedClockTick (); +	void InvokeTickCalls ();+ 	/* @GenerateCBinding, GeneratePInvoke */ 	guint AddTimeout (gint priority, guint ms_interval, GSourceFunc func, gpointer timeout_data); 	/* @GenerateCBinding, GeneratePInvoke */diff --git a/src/window-gtk.cpp b/src/window-gtk.cppindex c556347..286b89e 100644--- a/src/window-gtk.cpp+++ b/src/window-gtk.cpp@@ -13,6 +13,7 @@   #include "window-gtk.h" #include "deployment.h"+#include "timemanager.h"  MoonWindowGtk::MoonWindowGtk (bool fullscreen, int w, int h, MoonWindow *parent) 	: MoonWindow (w, h)@@ -424,8 +425,10 @@ MoonWindowGtk::button_press (GtkWidget *widget, GdkEventButton *event, gpointer 	if (event->button != 1 && event->button != 3) 		return false; -	if (window->surface)+	if (window->surface) {+		window->surface->GetTimeManager()->InvokeTickCalls(); 		window->surface->HandleUIButtonPress (event);+	} 	 	// If we don't support right clicks (i.e. inside the browser) 	// return false here@@ -444,8 +447,10 @@ MoonWindowGtk::button_release (GtkWidget *widget, GdkEventButton *event, gpointe  	Deployment::SetCurrent (window->GetDeployment ()); -	if (window->surface)+	if (window->surface) {+		window->surface->GetTimeManager()->InvokeTickCalls(); 		window->surface->HandleUIButtonRelease (event);+	} 	// ignore HandleUIButtonRelease's return value, and always 	// return true here, or it gets bubbled up to firefox. 	return true;@@ -458,8 +463,10 @@ MoonWindowGtk::scroll (GtkWidget *widget, GdkEventScroll *event, gpointer data)  	Deployment::SetCurrent (window->GetDeployment ()); -	if (window->surface)+	if (window->surface) {+		window->surface->GetTimeManager()->InvokeTickCalls(); 		window->surface->HandleUIScroll (event);+	} 	// ignore HandleUIScroll's return value, and always 	// return true here, or it gets bubbled up to firefox. 	return true;@@ -472,8 +479,10 @@ MoonWindowGtk::motion_notify (GtkWidget *widget, GdkEventMotion *event, gpointer  	Deployment::SetCurrent (window->GetDeployment ()); -	if (window->surface)+	if (window->surface) {+		window->surface->GetTimeManager()->InvokeTickCalls(); 		window->surface->HandleUIMotion (event);+	} 	// ignore HandleUIMotion's return value, and always 	// return true here, or it gets bubbled up to firefox. 	return true;@@ -486,7 +495,13 @@ MoonWindowGtk::crossing_notify (GtkWidget *widget, GdkEventCrossing *event, gpoi  	Deployment::SetCurrent (window->GetDeployment ()); -	return window->surface ? window->surface->HandleUICrossing (event) : false;+	if (window->surface) {+		window->surface->GetTimeManager()->InvokeTickCalls();+		window->surface->HandleUICrossing (event);+		return true;+	}++	return false; }  gboolean@@ -496,7 +511,13 @@ MoonWindowGtk::focus_in (GtkWidget *widget, GdkEventFocus *event, gpointer user_  	Deployment::SetCurrent (window->GetDeployment ()); -	return window->surface ? window->surface->HandleUIFocusIn (event) : false;+	if (window->surface) {+		window->surface->GetTimeManager()->InvokeTickCalls();+		window->surface->HandleUIFocusIn (event);+		return true;+	}++	return false; }  gboolean@@ -506,7 +527,14 @@ MoonWindowGtk::focus_out (GtkWidget *widget, GdkEventFocus *event, gpointer user  	Deployment::SetCurrent (window->GetDeployment ()); -	return window->surface ? window->surface->HandleUIFocusOut (event) : false;++	if (window->surface) {+		window->surface->GetTimeManager()->InvokeTickCalls();+		window->surface->HandleUIFocusOut (event);+		return true;+	}++	return false; }  gboolean@@ -515,7 +543,14 @@ MoonWindowGtk::key_press (GtkWidget *widget, GdkEventKey *event, gpointer user_d 	MoonWindowGtk *window = (MoonWindowGtk*)user_data;  	Deployment::SetCurrent (window->GetDeployment ());-	return window->surface ? window->surface->HandleUIKeyPress (event) : false;++	if (window->surface) {+		window->surface->GetTimeManager()->InvokeTickCalls();+		window->surface->HandleUIKeyPress (event);+		return true;+	}++	return false; }  gboolean@@ -524,7 +559,14 @@ MoonWindowGtk::key_release (GtkWidget *widget, GdkEventKey *event, gpointer user 	MoonWindowGtk *window = (MoonWindowGtk*)user_data;  	Deployment::SetCurrent (window->GetDeployment ());-	return window->surface ? window->surface->HandleUIKeyRelease (event) : false;++	if (window->surface) {+		window->surface->GetTimeManager()->InvokeTickCalls();+		window->surface->HandleUIKeyRelease (event);+		return true;+	}++	return false; }  void